https://github.com/mizvekov created 
https://github.com/llvm/llvm-project/pull/106335

As agreed on https://github.com/itanium-cxx-abi/cxx-abi/issues/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, they are correctly canonicalized, but this now leads to these 
TTPs being anonymous entities, where the mangling implementation correctly 
doesn't expect an anonymous declaration of this kind, leading to a crash.

Fixes #106182.

>From 2b94aa10a911162aff67a32ba623b0afd664761b Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizve...@gmail.com>
Date: Wed, 28 Aug 2024 00:34:12 -0300
Subject: [PATCH] [clang] mangle placeholder for deduced type as a
 template-prefix

As agreed on https://github.com/itanium-cxx-abi/cxx-abi/issues/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.
---
 clang/docs/ReleaseNotes.rst        |  2 ++
 clang/lib/AST/ItaniumMangle.cpp    | 12 ++++--------
 clang/test/CodeGenCXX/GH106182.cpp | 12 ++++++++++++
 3 files changed, 18 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/GH106182.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2c29d49ba20f03..d78e74bafe598f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -318,6 +318,8 @@ Bug Fixes to C++ Support
   of the current instantiation in all cases.
 - Fix evaluation of the index of dependent pack indexing expressions/types 
specifiers (#GH105900)
 - Correctly handle subexpressions of an immediate invocation in the presence 
of implicit casts. (#GH105558)
+- Mangle placeholders for deduced types as a template-prefix, such that 
mangling
+  of template template parameters uses the correct production. (#GH106182)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 976670d1efa561..1ce51f65dabd75 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4442,14 +4442,10 @@ void CXXNameMangler::mangleType(const 
DeducedTemplateSpecializationType *T) {
   if (!Deduced.isNull())
     return mangleType(Deduced);
 
-  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
-  assert(TD && "shouldn't form deduced TST unless we know we have a template");
-
-  if (mangleSubstitution(TD))
-    return;
-
-  mangleName(GlobalDecl(TD));
-  addSubstitution(TD);
+  TemplateName TN = T->getTemplateName();
+  assert(TN.getAsTemplateDecl() &&
+         "shouldn't form deduced TST unless we know we have a template");
+  mangleType(TN);
 }
 
 void CXXNameMangler::mangleType(const AtomicType *T) {
diff --git a/clang/test/CodeGenCXX/GH106182.cpp 
b/clang/test/CodeGenCXX/GH106182.cpp
new file mode 100644
index 00000000000000..401dadfd6de8b7
--- /dev/null
+++ b/clang/test/CodeGenCXX/GH106182.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++20 %s -triple %itanium_abi_triple -emit-llvm -o - | 
FileCheck %s
+
+template <template <class> class S>
+void create_unique()
+  requires (S{0}, true) {}
+
+template <class Fn> struct A {
+  constexpr A(Fn) {};
+};
+
+template void create_unique<A>();
+// CHECK: @_Z13create_uniqueI1AEvvQcmtlT_Li0EELb1E(

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to