Skip to content

Commit dc58cd1

Browse files
committed
PR48169: Fix crash generating debug info for class non-type template
parameters. It appears that LLVM isn't able to generate a DW_AT_const_value for a constant of class type, but if it could, we'd match GCC's debug info in this case, and in the interim we no longer crash.
1 parent 6ddc237 commit dc58cd1

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,12 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
19201920
V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
19211921
} else if (const auto *GD = dyn_cast<MSGuidDecl>(D)) {
19221922
V = CGM.GetAddrOfMSGuidDecl(GD).getPointer();
1923+
} else if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
1924+
if (T->isRecordType())
1925+
V = ConstantEmitter(CGM).emitAbstract(
1926+
SourceLocation(), TPO->getValue(), TPO->getType());
1927+
else
1928+
V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer();
19231929
}
19241930
assert(V && "Failed to find template parameter pointer");
19251931
V = V->stripPointerCasts();

clang/test/CodeGenCXX/debug-info-template.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
1+
// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++20 | FileCheck %s
22

33
// CHECK: @tci = dso_local global %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]]
44
// CHECK: @tcn = dso_local global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]]
@@ -156,3 +156,26 @@ struct PaddingAtEndTemplate {
156156
};
157157

158158
PaddingAtEndTemplate<&PaddedObj> PaddedTemplateObj;
159+
160+
struct ClassTemplateArg {
161+
int a;
162+
float f;
163+
};
164+
template<ClassTemplateArg A> struct ClassTemplateArgTemplate {
165+
static constexpr const ClassTemplateArg &Arg = A;
166+
};
167+
168+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgTemplate<{1, 2.000000e+00}>", {{.*}}, templateParams: ![[CLASS_TEMP_ARGS:[0-9]*]],
169+
// CHECK: ![[CLASS_TEMP_ARG_CONST_REF_TYPE:[0-9]*]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: ![[CLASS_TEMP_ARG_CONST_TYPE:[0-9]*]],
170+
// CHECK: ![[CLASS_TEMP_ARG_CONST_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[CLASS_TEMP_ARG_TYPE:[0-9]*]])
171+
// CHECK: ![[CLASS_TEMP_ARG_TYPE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArg",
172+
// CHECK: ![[CLASS_TEMP_ARGS]] = !{![[CLASS_TEMP_ARG:[0-9]*]]}
173+
// CHECK: ![[CLASS_TEMP_ARG]] = !DITemplateValueParameter(name: "A", type: ![[CLASS_TEMP_ARG_TYPE]], value: %{{[^ *]+}} { i32 1, float 2.000000e+00 })
174+
ClassTemplateArgTemplate<ClassTemplateArg{1, 2.0f}> ClassTemplateArgObj;
175+
176+
template<const ClassTemplateArg&> struct ClassTemplateArgRefTemplate {};
177+
ClassTemplateArgRefTemplate<ClassTemplateArgObj.Arg> ClassTemplateArgRefObj;
178+
179+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgRefTemplate<<template param ClassTemplateArg{1, 2.000000e+00}> >", {{.*}}, templateParams: ![[CLASS_TEMP_REF_ARGS:[0-9]*]],
180+
// CHECK: ![[CLASS_TEMP_REF_ARGS]] = !{![[CLASS_TEMP_REF_ARG:[0-9]*]]}
181+
// CHECK: ![[CLASS_TEMP_REF_ARG]] = !DITemplateValueParameter(type: ![[CLASS_TEMP_ARG_CONST_REF_TYPE]], value: %{{.*}}* @_ZTAXtl16ClassTemplateArgLi1ELf40000000EEE)

0 commit comments

Comments
 (0)