https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/126206

When substituting for rewrite purposes, as in rebuilding constraints for a 
synthesized deduction guide, it assumed that packs were in `PackExpansion*` 
form, such that the instantiator could extract a pattern. For type aliases 
CTAD, while rebuilding their associated constraints, we rebuild the template 
arguments using `TransformTemplateArgument()`, which did not guarantee the 
establishment of PackExpansions as `getInjectedTemplateArguments()` does.

This patch fixes that by making it call `RebuildPackExpansion()` if the 
transformed arguments are still having unexpanded parameter packs.

No release note as I think this is a good candidate for backporting.

Fixes #124715 

>From 2fece00684322b1ebd57a0d94f14c21cc570e262 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Fri, 7 Feb 2025 17:15:05 +0800
Subject: [PATCH] [Clang] Form PackExpansionTypes of TemplateArguments for
 rewrite substitution

When substituting for rewrite purposes, as in rebuilding constraints for a 
synthesized
deduction guide, it assumed that packs were in PackExpansion* form, such that 
the
instantiator could extract a pattern. For type aliases CTAD, while rebuilding 
their
associated constraints, we rebuild the template arguments using 
TransformTemplateArgument(),
which did not guarantee the establishment of PackExpansions as 
getInjectedTemplateArguments() does.

This patch fixes that by making it call RebuildPackExpansion() if the
transformed arguments are still having unexpanded parameter packs.
---
 clang/lib/Sema/SemaTemplateInstantiate.cpp |  8 +++-
 clang/test/AST/ast-dump-ctad-alias.cpp     | 44 ++++++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 12e98a33d07853e..522bd418e2f1881 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1627,8 +1627,14 @@ namespace {
           TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
               pack, QualType(), SourceLocation{});
           TemplateArgumentLoc Output;
-          if (SemaRef.SubstTemplateArgument(Input, TemplateArgs, Output))
+          if (TransformTemplateArgument(Input, Output, Uneval))
             return true; // fails
+          if (Output.getArgument().containsUnexpandedParameterPack())
+            // FIXME: Is EllipsisLoc necessary? This pack expansion merely
+            // serves as a placeholder type for future rewrite-substitution
+            // (e.g. into constraint expressions.)
+            Output =
+                RebuildPackExpansion(Output, SourceLocation{}, std::nullopt);
           TArgs.push_back(Output.getArgument());
         }
         Output = SemaRef.getTrivialTemplateArgumentLoc(
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp 
b/clang/test/AST/ast-dump-ctad-alias.cpp
index b1631f7822ce017..464808af784c2c3 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -156,3 +156,47 @@ ATemplatedClass2 test2(list);
 // CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible
 
 } // namespace GH90209
+
+namespace GH124715 {
+
+template <class T, class... Args>
+concept invocable = true;
+
+template <class T, class... Args> struct Struct {
+  template <class U>
+    requires invocable<U, Args...>
+  Struct(U, Args...) {}
+};
+
+template <class Lambda, class... Args>
+Struct(Lambda lambda, Args... args) -> Struct<Lambda, Args...>;
+
+template <class T, class... Ts> using Alias = Struct<T, Ts...>;
+
+void foo() {
+  Alias([](int) {}, 0);
+}
+
+// CHECK:      |-FunctionTemplateDecl {{.*}} implicit <deduction guide for 
Alias>
+// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T
+// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 1 ... Ts
+// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 2 U
+// CHECK-NEXT: | |-BinaryOperator {{.*}} 'bool' '&&'
+// CHECK-NEXT: | | |-ConceptSpecializationExpr {{.*}} 'bool' Concept {{.*}} 
'invocable'
+// CHECK-NEXT: | | | |-ImplicitConceptSpecializationDecl {{.*}}
+// CHECK-NEXT: | | | | |-TemplateArgument type 'type-parameter-0-2'
+// CHECK-NEXT: | | | | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-2' 
dependent depth 0 index 2
+// CHECK-NEXT: | | | | `-TemplateArgument pack '<type-parameter-0-1...>'
+// CHECK-NEXT: | | | |   `-TemplateArgument type 'type-parameter-0-1...'
+// CHECK-NEXT: | | | |     `-PackExpansionType {{.*}} 'type-parameter-0-1...' 
dependent
+// CHECK-NEXT: | | | |       `-TemplateTypeParmType {{.*}} 
'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index 1 pack
+// CHECK-NEXT: | | | |-TemplateArgument {{.*}} type 'U':'type-parameter-0-2'
+// CHECK-NEXT: | | | | `-TemplateTypeParmType {{.*}} 'U' dependent depth 0 
index 2
+// CHECK-NEXT: | | | |   `-TemplateTypeParm {{.*}} 'U'
+// CHECK-NEXT: | | | `-TemplateArgument {{.*}} type 
'Ts...':'type-parameter-0-1...'
+// CHECK-NEXT: | | |   `-PackExpansionType {{.*}} 'Ts...' dependent
+// CHECK-NEXT: | | |     `-TemplateTypeParmType {{.*}} 'Ts' dependent 
contains_unexpanded_pack depth 0 index 1 pack
+// CHECK-NEXT: | | |       `-TemplateTypeParm {{.*}} 'Ts'
+// CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
+
+} // namespace GH124715

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

Reply via email to