From 30305bec25cac981c6d4a3b8be004401310a82a7 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 13 Nov 2012 02:31:58 +0000 Subject: [PATCH] Use the 'count' attribute instead of the 'upper_bound' attribute. If we have a type 'int a[1]' and a type 'int b[0]', the generated DWARF is the same for both of them because we use the 'upper_bound' attribute. Instead use the 'count' attrbute, which gives the correct number of elements in the array. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167807 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 21 +++++++------ test/CodeGen/debug-info-zero-length-arrays.c | 33 ++++++++++++++++++++ test/CodeGenCXX/debug-info-flex-member.cpp | 2 +- 3 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 test/CodeGen/debug-info-zero-length-arrays.c diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 80fa09be74..3843889635 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1473,23 +1473,23 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) { llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit); - int64_t NumElems = Ty->getNumElements(); + int64_t UpperBound = Ty->getNumElements(); int64_t LowerBound = 0; - if (NumElems == 0) + if (UpperBound == 0) // If number of elements are not known then this is an unbounded array. // Use Low = 1, Hi = 0 to express such arrays. LowerBound = 1; else - --NumElems; + --UpperBound; - llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, NumElems); + llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, UpperBound, + Ty->getNumElements()); llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscript); uint64_t Size = CGM.getContext().getTypeSize(Ty); uint64_t Align = CGM.getContext().getTypeAlign(Ty); - return - DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray); + return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray); } llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, @@ -1525,9 +1525,11 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, while ((Ty = dyn_cast(EltTy))) { int64_t UpperBound = 0; int64_t LowerBound = 0; + uint64_t Count = 0; if (const ConstantArrayType *CAT = dyn_cast(Ty)) { - if (CAT->getSize().getZExtValue()) - UpperBound = CAT->getSize().getZExtValue() - 1; + Count = CAT->getSize().getZExtValue(); + if (Count) + UpperBound = Count - 1; } else // This is an unbounded array. Use Low = 1, Hi = 0 to express such // arrays. @@ -1535,7 +1537,8 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, // FIXME: Verify this is right for VLAs. Subscripts.push_back(DBuilder.getOrCreateSubrange(LowerBound, - UpperBound)); + UpperBound, + Count)); EltTy = Ty->getElementType(); } diff --git a/test/CodeGen/debug-info-zero-length-arrays.c b/test/CodeGen/debug-info-zero-length-arrays.c new file mode 100644 index 0000000000..68f7c016ff --- /dev/null +++ b/test/CodeGen/debug-info-zero-length-arrays.c @@ -0,0 +1,33 @@ +// RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s + +// + +// The subrange for a type 'int[1]' and 'int[0]' should be different. Use the +// 'count' attribute instead of the 'upper_bound' attribute do disabmiguate the +// DIE. + +struct foo { + int a; + int b[1]; +}; + +struct bar { + int a; + int b[0]; +}; + +int main() +{ + struct foo my_foo; + struct bar my_bar; + + my_foo.a = 3; + my_bar.a = 5; + + return my_foo.a + my_bar.a; +} + +// The third metadata operand is the count. +// +// CHECK: metadata !{i32 786465, i64 0, i64 0, i64 1} ; [ DW_TAG_subrange_type ] +// CHECK: metadata !{i32 786465, i64 0, i64 0, i64 0} ; [ DW_TAG_subrange_type ] diff --git a/test/CodeGenCXX/debug-info-flex-member.cpp b/test/CodeGenCXX/debug-info-flex-member.cpp index b6aa6dac6b..72a5bf8461 100644 --- a/test/CodeGenCXX/debug-info-flex-member.cpp +++ b/test/CodeGenCXX/debug-info-flex-member.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s -// CHECK: metadata !{i32 {{.*}}, i64 1, i64 0} ; [ DW_TAG_subrange_type ] +// CHECK: metadata !{i32 {{.*}}, i64 1, i64 0, i64 0} ; [ DW_TAG_subrange_type ] struct StructName { int member[];