Skip to content

Commit b86ebec

Browse files
committed
[clang] mangle placeholder for deduced type as a template-prefix
As agreed on itanium-cxx-abi/cxx-abi#109 these placeholders should be mangled as a `template-prefix` production. ``` <template-prefix> ::= <template unqualified-name> # global template ::= <prefix> <template unqualified-name> # nested template ::= <template-param> # template template parameter ::= <substitution> ``` Previous to this patch, the template template parameter case was not handled, and template template parameters were incorrectly being handled as unqualified-names. Before #95202, DeducedTemplateType was not canonicalized correctly, so that template template parameter declarations were retained uncanonicalized. After #95202 patch, we correctly canonicalize them, but now this leads to handling these TTPs as anonymous entities, where the implementation correctly doesn't expect an anonymous declaration of this kind, leading to a crash. Fixes #106182.
1 parent fac7e87 commit b86ebec

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ Bug Fixes to C++ Support
319319
- Fix evaluation of the index of dependent pack indexing expressions/types specifiers (#GH105900)
320320
- Correctly handle subexpressions of an immediate invocation in the presence of implicit casts. (#GH105558)
321321
- Clang now correctly handles direct-list-initialization of a structured bindings from an array. (#GH31813)
322+
- Mangle placeholders for deduced types as a template-prefix, such that mangling
323+
of template template parameters uses the correct production. (#GH106182)
322324

323325
Bug Fixes to AST Handling
324326
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4442,14 +4442,10 @@ void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) {
44424442
if (!Deduced.isNull())
44434443
return mangleType(Deduced);
44444444

4445-
TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
4446-
assert(TD && "shouldn't form deduced TST unless we know we have a template");
4447-
4448-
if (mangleSubstitution(TD))
4449-
return;
4450-
4451-
mangleName(GlobalDecl(TD));
4452-
addSubstitution(TD);
4445+
TemplateName TN = T->getTemplateName();
4446+
assert(TN.getAsTemplateDecl() &&
4447+
"shouldn't form deduced TST unless we know we have a template");
4448+
mangleType(TN);
44534449
}
44544450

44554451
void CXXNameMangler::mangleType(const AtomicType *T) {

clang/test/CodeGenCXX/GH106182.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -std=c++20 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
2+
3+
template <template <class> class S>
4+
void create_unique()
5+
requires (S{0}, true) {}
6+
7+
template <class Fn> struct A {
8+
constexpr A(Fn) {};
9+
};
10+
11+
template void create_unique<A>();
12+
// CHECK: @_Z13create_uniqueI1AEvvQcmtlT_Li0EELb1E(

0 commit comments

Comments
 (0)