diff --git a/clang/test/CodeGenCXX/debug-info-enum-metadata-collision.cpp b/clang/test/CodeGenCXX/debug-info-enum-metadata-collision.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-enum-metadata-collision.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s + +// Test that clang doesn't crash while resolving temporary debug metadata of +// a record with collisions in the record's enum users. + +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, +// CHECK-SAME: scope: [[SCOPE:![0-9]+]] +// CHECK-SAME: elements: [[ELEMENTS:![0-9]+]] +// CHECK: [[SCOPE]] = !DICompositeType(tag: DW_TAG_structure_type +// CHECK-SAME: name: "Struct1" +// CHECK: [[ELEMENTS]] = !{[[ELEMENT:![0-9]+]]} +// CHECK: [[ELEMENT]] = !DIEnumerator(name: "enumValue1" + +template struct Struct1 { + enum { enumValue1 }; + Struct1(); +}; +void function2() { + struct Struct3 {}; + int i = Struct1::enumValue1; +} +void function3() { + struct Struct3 {}; + int i = Struct1::enumValue1; +} diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -48,7 +48,7 @@ Function *LabelFn; ///< llvm.dbg.label Function *AddrFn; ///< llvm.dbg.addr - SmallVector AllEnumTypes; + SmallVector AllEnumTypes; /// Track the RetainTypes, since they can be updated later on. SmallVector AllRetainTypes; SmallVector AllSubprograms; diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -84,7 +84,9 @@ } if (!AllEnumTypes.empty()) - CUNode->replaceEnumTypes(MDTuple::get(VMContext, AllEnumTypes)); + CUNode->replaceEnumTypes(MDTuple::get( + VMContext, SmallVector(AllEnumTypes.begin(), + AllEnumTypes.end()))); SmallVector RetainValues; // Declarations and definitions of the same type may be retained. Some @@ -556,7 +558,7 @@ getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0, IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements, 0, nullptr, nullptr, UniqueIdentifier); - AllEnumTypes.push_back(CTy); + AllEnumTypes.emplace_back(CTy); trackIfUnresolved(CTy); return CTy; }