rnk created this revision. rnk added reviewers: JDevlieghere, aprantl, ormris, dblaikie. Herald added a project: clang.
Fixes PR41677 Consider: template <typename LHS, typename RHS> constexpr bool is_same_v = false; template <typename T> constexpr bool is_same_v<T, T> = true; template constexpr bool is_same_v<int, int>; Before this change, when emitting debug info for the `is_same_v<int, int>` global variable, clang would crash because it would try to use the template parameter list from the partial specialization to give parameter names to template arguments. This doesn't work in general, since a partial specialization can have fewer arguments than the primary template. Therefore, always use the primary template. Hypothetically we could try to use the parameter names from the partial specialization when possible, but it's not clear this really helps debugging in practice. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D61408 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-template-member.cpp clang/test/CodeGenCXX/debug-info-var-template-partial.cpp Index: clang/test/CodeGenCXX/debug-info-var-template-partial.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-var-template-partial.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s + +template <typename LHS, typename RHS> constexpr bool is_same_v = false; +template <typename T> constexpr bool is_same_v<T, T> = true; + +void escape(const bool *); +void useit() { + escape(&is_same_v<int, int>); + static_assert(is_same_v<int, int>, "should get partial spec"); +} + +// Note that the template arguments for the instantiated variable use the +// parameter names from the primary template. The partial specialization might +// not have enough parameters. + +// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_Z9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]]) +// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]} +// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]]) +// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]]) Index: clang/test/CodeGenCXX/debug-info-template-member.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-template-member.cpp +++ clang/test/CodeGenCXX/debug-info-template-member.cpp @@ -30,7 +30,7 @@ // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "var" // CHECK-SAME: templateParams: {{![0-9]+}} -// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}}) +// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}}) // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "varray" // CHECK-SAME: templateParams: {{![0-9]+}} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -1827,26 +1827,14 @@ } llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL, - llvm::DIFile *Unit) { - if (auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL)) { - auto T = TS->getSpecializedTemplateOrPartial(); - auto TA = TS->getTemplateArgs().asArray(); - // Collect parameters for a partial specialization - if (T.is<VarTemplatePartialSpecializationDecl *>()) { - const TemplateParameterList *TList = - T.get<VarTemplatePartialSpecializationDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - - // Collect parameters for an explicit specialization - if (T.is<VarTemplateDecl *>()) { - const TemplateParameterList *TList = T.get<VarTemplateDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - } - return llvm::DINodeArray(); + llvm::DIFile *Unit) { + auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL); + if (!TS) + return llvm::DINodeArray(); + VarTemplateDecl *T = TS->getSpecializedTemplate(); + const TemplateParameterList *TList = T->getTemplateParameters(); + auto TA = TS->getTemplateArgs().asArray(); + return CollectTemplateParams(TList, TA, Unit); } llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
Index: clang/test/CodeGenCXX/debug-info-var-template-partial.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-var-template-partial.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s + +template <typename LHS, typename RHS> constexpr bool is_same_v = false; +template <typename T> constexpr bool is_same_v<T, T> = true; + +void escape(const bool *); +void useit() { + escape(&is_same_v<int, int>); + static_assert(is_same_v<int, int>, "should get partial spec"); +} + +// Note that the template arguments for the instantiated variable use the +// parameter names from the primary template. The partial specialization might +// not have enough parameters. + +// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_Z9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]]) +// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]} +// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]]) +// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]]) Index: clang/test/CodeGenCXX/debug-info-template-member.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-template-member.cpp +++ clang/test/CodeGenCXX/debug-info-template-member.cpp @@ -30,7 +30,7 @@ // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "var" // CHECK-SAME: templateParams: {{![0-9]+}} -// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}}) +// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}}) // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "varray" // CHECK-SAME: templateParams: {{![0-9]+}} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -1827,26 +1827,14 @@ } llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL, - llvm::DIFile *Unit) { - if (auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL)) { - auto T = TS->getSpecializedTemplateOrPartial(); - auto TA = TS->getTemplateArgs().asArray(); - // Collect parameters for a partial specialization - if (T.is<VarTemplatePartialSpecializationDecl *>()) { - const TemplateParameterList *TList = - T.get<VarTemplatePartialSpecializationDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - - // Collect parameters for an explicit specialization - if (T.is<VarTemplateDecl *>()) { - const TemplateParameterList *TList = T.get<VarTemplateDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - } - return llvm::DINodeArray(); + llvm::DIFile *Unit) { + auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL); + if (!TS) + return llvm::DINodeArray(); + VarTemplateDecl *T = TS->getSpecializedTemplate(); + const TemplateParameterList *TList = T->getTemplateParameters(); + auto TA = TS->getTemplateArgs().asArray(); + return CollectTemplateParams(TList, TA, Unit); } llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits