IR: Allow MDSubrange to have 'count: -1'
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 18 Feb 2015 23:17:51 +0000 (23:17 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 18 Feb 2015 23:17:51 +0000 (23:17 +0000)
It turns out that `count: -1` is a special value indicating an empty
array, such as `Values` in:

    struct T {
      unsigned Count;
      int Values[];
    };

Handle it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229769 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLParser.cpp
test/Assembler/invalid-mdsubrange-count-negative.ll
test/Assembler/mdsubrange-empty-array.ll [new file with mode: 0644]
unittests/IR/MetadataTest.cpp

index 76365ea22334ff2ec3eafaee8a74d871365af809..0d748610742a5aeaad83c8a52fc5f32554ef63c6 100644 (file)
@@ -3276,7 +3276,7 @@ bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) {
 ///   ::= !MDSubrange(count: 30, lowerBound: 2)
 bool LLParser::ParseMDSubrange(MDNode *&Result, bool IsDistinct) {
 #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
-  REQUIRED(count, MDUnsignedField, (0, UINT64_MAX >> 1));                      \
+  REQUIRED(count, MDSignedField, (-1, -1, INT64_MAX));                         \
   OPTIONAL(lowerBound, MDSignedField, );
   PARSE_MD_FIELDS();
 #undef VISIT_MD_FIELDS
index 99cc8876750cb301eccae93bc24881f072f3bd7f..92c0b4e7ca48c5eb9a936bcf65150791b5eab9bc 100644 (file)
@@ -1,4 +1,7 @@
 ; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
 
-; CHECK: [[@LINE+1]]:25: error: expected unsigned integer
-!0 = !MDSubrange(count: -3)
+; CHECK-NOT: error
+!0 = !MDSubrange(count: -1)
+
+; CHECK: <stdin>:[[@LINE+1]]:25: error: value for 'count' too small, limit is -1
+!0 = !MDSubrange(count: -2)
diff --git a/test/Assembler/mdsubrange-empty-array.ll b/test/Assembler/mdsubrange-empty-array.ll
new file mode 100644 (file)
index 0000000..fa05582
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+; CHECK: !named = !{!0, !0, !1, !2}
+!named = !{!0, !1, !2, !3}
+
+; CHECK:      !0 = !MDSubrange(count: -1)
+; CHECK-NEXT: !1 = !MDSubrange(count: -1, lowerBound: 4)
+; CHECK-NEXT: !2 = !MDSubrange(count: -1, lowerBound: -5)
+!0 = !MDSubrange(count: -1)
+!1 = !MDSubrange(count: -1, lowerBound: 0)
+
+!2 = !MDSubrange(count: -1, lowerBound: 4)
+!3 = !MDSubrange(count: -1, lowerBound: -5)
index fc2ed73d89c0329d45e2d1ca3018d0e7f04f568e..b6ee46a5d7b878f5aa79412b56847b60735f24ab 100644 (file)
@@ -670,6 +670,14 @@ TEST_F(MDSubrangeTest, get) {
   EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
 }
 
+TEST_F(MDSubrangeTest, getEmptyArray) {
+  auto *N = MDSubrange::get(Context, -1, 0);
+  EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+  EXPECT_EQ(-1, N->getCount());
+  EXPECT_EQ(0, N->getLo());
+  EXPECT_EQ(N, MDSubrange::get(Context, -1, 0));
+}
+
 typedef MetadataTest MDEnumeratorTest;
 
 TEST_F(MDEnumeratorTest, get) {