From dc58cd1480374a6d5dbf87e8a2424811c0003ce3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 15 Nov 2020 17:40:57 -0800 Subject: [PATCH 1/2] 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. --- clang/lib/CodeGen/CGDebugInfo.cpp | 6 +++++ clang/test/CodeGenCXX/debug-info-template.cpp | 25 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 6f77aed526bc4a..97337e00180ea6 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1920,6 +1920,12 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars); } else if (const auto *GD = dyn_cast(D)) { V = CGM.GetAddrOfMSGuidDecl(GD).getPointer(); + } else if (const auto *TPO = dyn_cast(D)) { + if (T->isRecordType()) + V = ConstantEmitter(CGM).emitAbstract( + SourceLocation(), TPO->getValue(), TPO->getType()); + else + V = CGM.GetAddrOfTemplateParamObject(TPO).getPointer(); } assert(V && "Failed to find template parameter pointer"); V = V->stripPointerCasts(); diff --git a/clang/test/CodeGenCXX/debug-info-template.cpp b/clang/test/CodeGenCXX/debug-info-template.cpp index f52380a62ca6b9..a6edd59171b293 100644 --- a/clang/test/CodeGenCXX/debug-info-template.cpp +++ b/clang/test/CodeGenCXX/debug-info-template.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s +// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++20 | FileCheck %s // CHECK: @tci = dso_local global %"struct.TC::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]] // CHECK: @tcn = dso_local global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]] @@ -156,3 +156,26 @@ struct PaddingAtEndTemplate { }; PaddingAtEndTemplate<&PaddedObj> PaddedTemplateObj; + +struct ClassTemplateArg { + int a; + float f; +}; +template struct ClassTemplateArgTemplate { + static constexpr const ClassTemplateArg &Arg = A; +}; + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgTemplate<{1, 2.000000e+00}>", {{.*}}, templateParams: ![[CLASS_TEMP_ARGS:[0-9]*]], +// CHECK: ![[CLASS_TEMP_ARG_CONST_REF_TYPE:[0-9]*]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: ![[CLASS_TEMP_ARG_CONST_TYPE:[0-9]*]], +// CHECK: ![[CLASS_TEMP_ARG_CONST_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[CLASS_TEMP_ARG_TYPE:[0-9]*]]) +// CHECK: ![[CLASS_TEMP_ARG_TYPE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArg", +// CHECK: ![[CLASS_TEMP_ARGS]] = !{![[CLASS_TEMP_ARG:[0-9]*]]} +// CHECK: ![[CLASS_TEMP_ARG]] = !DITemplateValueParameter(name: "A", type: ![[CLASS_TEMP_ARG_TYPE]], value: %{{[^ *]+}} { i32 1, float 2.000000e+00 }) +ClassTemplateArgTemplate ClassTemplateArgObj; + +template struct ClassTemplateArgRefTemplate {}; +ClassTemplateArgRefTemplate ClassTemplateArgRefObj; + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgRefTemplate<