https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/223340

>From f7ae9a62e7d82a71be4f2c1c8f153a85b0d2f2a7 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Mon, 14 Sep 2026 17:31:25 +0800
Subject: [PATCH 1/2] [Clang] Fix synthesizing of alias CTAD constraints

buildAssociatedConstraints reconstructs a template parameter list relative
to its primary template. However it didn't match the construction of
the CTAD guide very precisely.
---
 clang/docs/ReleaseNotes.md                    |  2 ++
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 29 ++++++++++++-------
 clang/test/SemaCXX/ctad.cpp                   | 29 +++++++++++++++++++
 3 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 043a0ddae2a6c..be67a1b3779d8 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -579,6 +579,8 @@ features cannot lower the translation-unit ABI level;
 - Fixed a crash when a using-declaration naming an unresolvable member of a
   dependent base was shadowed by an invalid using-declaration. (#GH209427)
 
+- Fixed a CTAD bug when combining with concepts. (#GH124715)
+
 - Fixed a regression where an internal-linkage function (e.g. a `static` or
   anonymous-namespace helper) declared in the global module fragment of the
   current translation unit was removed from the overload set when the calling
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 1a488ece55d25..e1000372985fc 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -998,11 +998,19 @@ buildAssociatedConstraints(Sema &SemaRef, 
FunctionTemplateDecl *F,
           AliasTemplate->getInstantiatedFromMemberTemplate())
     AdjustDepth = PrimaryTemplate->getTemplateDepth();
 
+  // FIXME: We're rebuilding the synthesized template parameter list again
+  // Consider reuse the template parameter from its caller.
+
   // We rebuild all template parameters with the uninstantiated depth, and
   // build template arguments refer to them.
-  SmallVector<TemplateArgument> AdjustedAliasTemplateArgs;
+  SmallVector<TemplateArgument> AdjustedAliasTemplateArgs(
+      AliasTemplate->getTemplateParameters()->size());
 
-  for (auto *TP : *AliasTemplate->getTemplateParameters()) {
+  unsigned N = 0;
+  for (unsigned Index = 0; Index != AdjustedAliasTemplateArgs.size(); ++Index) 
{
+    if (DeduceResults[Index].isNull())
+      continue;
+    auto *TP = AliasTemplate->getTemplateParameters()->getParam(Index);
     // Rebuild any internal references to earlier parameters and reindex
     // as we go.
     MultiLevelTemplateArgumentList Args;
@@ -1010,21 +1018,22 @@ buildAssociatedConstraints(Sema &SemaRef, 
FunctionTemplateDecl *F,
     Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
     NamedDecl *NewParam = transformTemplateParameter(
         SemaRef, AliasTemplate->getDeclContext(), TP, Args,
-        /*NewIndex=*/AdjustedAliasTemplateArgs.size(),
-        getDepthAndIndex(TP).first + AdjustDepth);
+        /*NewIndex=*/N++, getDepthAndIndex(TP).first + AdjustDepth);
 
     TemplateArgument NewTemplateArgument =
         Context.getInjectedTemplateArg(NewParam);
-    AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
+    AdjustedAliasTemplateArgs[Index] = NewTemplateArgument;
   }
+  assert(FirstUndeducedParamIdx == N);
+
   // Template arguments used to transform the template arguments in
   // DeducedResults.
   SmallVector<TemplateArgument> TemplateArgsForBuildingRC(
       F->getTemplateParameters()->size());
   // Transform the transformed template args
-  MultiLevelTemplateArgumentList Args;
-  Args.setKind(TemplateSubstitutionKind::Rewrite);
-  Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
+  MultiLevelTemplateArgumentList ArgsForDeducedParams;
+  ArgsForDeducedParams.setKind(TemplateSubstitutionKind::Rewrite);
+  ArgsForDeducedParams.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
 
   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
     const auto &D = DeduceResults[Index];
@@ -1047,7 +1056,7 @@ buildAssociatedConstraints(Sema &SemaRef, 
FunctionTemplateDecl *F,
     TemplateArgumentLoc Input =
         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
     TemplateArgumentLoc Output;
-    if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
+    if (!SemaRef.SubstTemplateArgument(Input, ArgsForDeducedParams, Output)) {
       assert(TemplateArgsForBuildingRC[Index].isNull() &&
              "InstantiatedArgs must be null before setting");
       TemplateArgsForBuildingRC[Index] = Output.getArgument();
@@ -1119,7 +1128,7 @@ buildAssociatedConstraints(Sema &SemaRef, 
FunctionTemplateDecl *F,
 Expr *buildIsDeducibleConstraint(Sema &SemaRef,
                                  TypeAliasTemplateDecl *AliasTemplate,
                                  QualType ReturnType,
-                                 SmallVector<NamedDecl *> TemplateParams) {
+                                 ArrayRef<NamedDecl *> TemplateParams) {
   ASTContext &Context = SemaRef.Context;
   // Constraint AST nodes must use uninstantiated depth.
   if (auto *PrimaryTemplate =
diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp
index 2a4e1c571ac5c..6517e88a8a831 100644
--- a/clang/test/SemaCXX/ctad.cpp
+++ b/clang/test/SemaCXX/ctad.cpp
@@ -197,3 +197,32 @@ namespace GH131342 {
   template <class T> using AA = A<T, val<T>>;
   AA a{0};
 } // namespace GH131342
+
+namespace GH124715_2 {
+
+template <class F, class... Args>
+using invoke_result_t = decltype(F()(Args()...));
+
+template <class F, class... Args>
+invoke_result_t<F, Args...> invoke(F f, Args... args);
+
+template <class F, class... Args>
+concept invocable = requires(F f, Args... args) {
+    invoke(f, args...);
+};
+
+template <class Ret, class... Args>
+struct A {
+    A(auto&&...) {}
+};
+
+template <class Lambda, class... Args>
+    requires invocable<Lambda, Args...>
+A(Lambda, Args...) -> A<invoke_result_t<Lambda, Args...>, Args...>;
+
+template <class T, class... Ts>
+using AliasName = A<T, Ts...>;
+
+AliasName aa([](int){}, 0);
+
+}

>From dec9c601da34631af5d8989bcfaed628d7cd2030 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Tue, 15 Sep 2026 16:39:52 +0800
Subject: [PATCH 2/2] Remove FIXME

---
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index e1000372985fc..5f656c01083d2 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -998,9 +998,6 @@ buildAssociatedConstraints(Sema &SemaRef, 
FunctionTemplateDecl *F,
           AliasTemplate->getInstantiatedFromMemberTemplate())
     AdjustDepth = PrimaryTemplate->getTemplateDepth();
 
-  // FIXME: We're rebuilding the synthesized template parameter list again
-  // Consider reuse the template parameter from its caller.
-
   // We rebuild all template parameters with the uninstantiated depth, and
   // build template arguments refer to them.
   SmallVector<TemplateArgument> AdjustedAliasTemplateArgs(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to