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

>From eba5a86714873b45d0c3b8d00af57e96a705644f Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Sun, 28 Sep 2025 10:40:26 +0800
Subject: [PATCH 1/3] [Clang] Ensure initialized NTTP expressions when building
 CTAD for type aliases

We missed calling CheckTemplateArgument when building CTAD deduction guides.
That ensures some InitExprs are correctly initialized, as in the test
that crashed due to incorrect NTTP initialization.

We don't use CheckTemplateArguments because, in CTAD synthesis, template
parameter packs don't always appear at the end of the parameter list,
unlike user-written ones mandated by the standard. This makes it
difficult for CheckTemplateArguments to determine how many arguments a
pack should match, leading to unnecessary complexity.

On the other hand, since we substitute non-deduced template parameters
with deduced ones, we need to fold the packs midway through substitution,
where CheckTemplateArgument is more convenient.

As a drive-by this also removes some dead code in SemaInit.
---
 clang/docs/ReleaseNotes.rst                   |  2 +-
 clang/lib/Sema/SemaInit.cpp                   |  5 +--
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 42 +++++++++++++++++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp  | 18 ++++++++
 4 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 98c889c08b329..888b202c538de 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -361,7 +361,7 @@ Bug Fixes in This Version
   first parameter. (#GH113323).
 - Fixed a crash with incompatible pointer to integer conversions in designated
   initializers involving string literals. (#GH154046)
-- Fix crash on CTAD for alias template. (#GH131342)
+- Fix crash on CTAD for alias template. (#GH131342), (#GH131408)
 - Clang now emits a frontend error when a function marked with the `flatten` 
attribute
   calls another function that requires target features not enabled in the 
caller. This
   prevents a fatal error in the backend.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index c97129336736b..0d0d2c00eb5d4 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -8219,8 +8219,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
       // InitializeTemporary entity for our target type.
       QualType Ty = Step->Type;
       bool IsTemporary = !S.Context.hasSameType(Entity.getType(), Ty);
-      InitializedEntity TempEntity = 
InitializedEntity::InitializeTemporary(Ty);
-      InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;
+      InitializedEntity InitEntity =
+          IsTemporary ? InitializedEntity::InitializeTemporary(Ty) : Entity;
       InitListChecker PerformInitList(S, InitEntity,
           InitList, Ty, /*VerifyOnly=*/false,
           /*TreatUnavailableAsInvalid=*/false);
@@ -8242,7 +8242,6 @@ ExprResult InitializationSequence::Perform(Sema &S,
 
       InitListExpr *StructuredInitList =
           PerformInitList.getFullyStructuredList();
-      CurInit.get();
       CurInit = shouldBindAsTemporary(InitEntity)
           ? S.MaybeBindToTemporary(StructuredInitList)
           : StructuredInitList;
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 3d54d1eb4373a..451ec3754ca70 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1171,17 +1171,38 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
   Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
     const auto &D = DeduceResults[Index];
+    auto *TP = F->getTemplateParameters()->getParam(Index);
     if (IsNonDeducedArgument(D)) {
       // 2): Non-deduced template parameters would be substituted later.
       continue;
     }
     TemplateArgumentLoc Input =
         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
-    TemplateArgumentLoc Output;
-    if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
+    TemplateArgumentListInfo Output;
+    if (!SemaRef.SubstTemplateArguments(Input, Args, Output)) {
       assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
              "InstantiatedArgs must be null before setting");
-      TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
+      Sema::CheckTemplateArgumentInfo CTAI;
+      if (Input.getArgument().getKind() == TemplateArgument::Pack) {
+        for (auto TA : Output.arguments()) {
+          if (SemaRef.CheckTemplateArgument(
+                  TP, TA, F, F->getLocation(), F->getLocation(),
+                  /*ArgumentPackIndex=*/-1, CTAI,
+                  Sema::CheckTemplateArgumentKind::CTAK_Specified))
+            return nullptr;
+        }
+        TemplateArgsForBuildingFPrime[Index] =
+            TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted);
+      } else {
+        assert(Output.arguments().size() == 1);
+        TemplateArgumentLoc Transformed = Output.arguments()[0];
+        if (SemaRef.CheckTemplateArgument(
+                TP, Transformed, F, F->getLocation(), F->getLocation(),
+                /*ArgumentPackIndex=*/-1, CTAI,
+                Sema::CheckTemplateArgumentKind::CTAK_Specified))
+          return nullptr;
+        TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
+      }
     }
   }
 
@@ -1202,8 +1223,21 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
 
     assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
            "The argument must be null before setting");
+    TemplateArgument Transformed = Context.getInjectedTemplateArg(NewParam);
+    if (NewParam->isTemplateParameterPack())
+      Transformed = *Transformed.pack_begin();
+    TemplateArgumentLoc TALoc = SemaRef.getTrivialTemplateArgumentLoc(
+        Transformed, QualType(), NewParam->getBeginLoc());
+    Sema::CheckTemplateArgumentInfo CTAI;
+    if (SemaRef.CheckTemplateArgument(
+            TP, TALoc, F, F->getLocation(), F->getLocation(),
+            /*ArgumentPackIndex=*/-1, CTAI,
+            Sema::CheckTemplateArgumentKind::CTAK_Specified))
+      return nullptr;
     TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
-        Context.getInjectedTemplateArg(NewParam);
+        NewParam->isTemplateParameterPack()
+            ? TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted)
+            : CTAI.SugaredConverted[0];
   }
 
   auto *TemplateArgListForBuildingFPrime =
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 2f1817d0ca7eb..d7ce966f46060 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -586,3 +586,21 @@ Baz a{};
 static_assert(__is_same(decltype(a), A<A<int>>));
 
 } // namespace GH133132
+
+namespace GH131408 {
+
+struct Node {};
+
+template <class T, Node>
+struct A {
+    A(T) {}
+};
+
+template <class T>
+using AA = A<T, {}>;
+
+AA a{0};
+
+static_assert(__is_same(decltype(a), A<int, Node{}>));
+
+}

>From 6e11a6fcdf3b8271cb549e097bb1a934b9c940e7 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Tue, 30 Sep 2025 07:53:49 +0800
Subject: [PATCH 2/3] No need to check conversions for non-deduced parameters

---
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 451ec3754ca70..39752d8fc5dd0 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1223,21 +1223,8 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
 
     assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
            "The argument must be null before setting");
-    TemplateArgument Transformed = Context.getInjectedTemplateArg(NewParam);
-    if (NewParam->isTemplateParameterPack())
-      Transformed = *Transformed.pack_begin();
-    TemplateArgumentLoc TALoc = SemaRef.getTrivialTemplateArgumentLoc(
-        Transformed, QualType(), NewParam->getBeginLoc());
-    Sema::CheckTemplateArgumentInfo CTAI;
-    if (SemaRef.CheckTemplateArgument(
-            TP, TALoc, F, F->getLocation(), F->getLocation(),
-            /*ArgumentPackIndex=*/-1, CTAI,
-            Sema::CheckTemplateArgumentKind::CTAK_Specified))
-      return nullptr;
     TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
-        NewParam->isTemplateParameterPack()
-            ? TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted)
-            : CTAI.SugaredConverted[0];
+        Context.getInjectedTemplateArg(NewParam);
   }
 
   auto *TemplateArgListForBuildingFPrime =

>From 349f172b009fa6166fb6c529bd778684fafe5c24 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Thu, 2 Oct 2025 13:15:53 +0800
Subject: [PATCH 3/3] Apply Matheus's feedback

---
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 46 +++++++++++--------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 39752d8fc5dd0..d1a2d531eecf3 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1179,30 +1179,38 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
     TemplateArgumentLoc Input =
         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
     TemplateArgumentListInfo Output;
-    if (!SemaRef.SubstTemplateArguments(Input, Args, Output)) {
-      assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
-             "InstantiatedArgs must be null before setting");
-      Sema::CheckTemplateArgumentInfo CTAI;
-      if (Input.getArgument().getKind() == TemplateArgument::Pack) {
-        for (auto TA : Output.arguments()) {
-          if (SemaRef.CheckTemplateArgument(
-                  TP, TA, F, F->getLocation(), F->getLocation(),
-                  /*ArgumentPackIndex=*/-1, CTAI,
-                  Sema::CheckTemplateArgumentKind::CTAK_Specified))
-            return nullptr;
-        }
-        TemplateArgsForBuildingFPrime[Index] =
-            TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted);
-      } else {
-        assert(Output.arguments().size() == 1);
-        TemplateArgumentLoc Transformed = Output.arguments()[0];
+    if (SemaRef.SubstTemplateArguments(Input, Args, Output))
+      return nullptr;
+    assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
+           "InstantiatedArgs must be null before setting");
+    // CheckTemplateArgument is necessary for NTTP initializations.
+    // FIXME: We may want to call CheckTemplateArguments instead, but we cannot
+    // match packs as usual, since packs can appear in the middle of the
+    // parameter list of a synthesized CTAD guide. See also the FIXME in
+    // test/SemaCXX/cxx20-ctad-type-alias.cpp:test25.
+    Sema::CheckTemplateArgumentInfo CTAI;
+    if (Input.getArgument().getKind() == TemplateArgument::Pack) {
+      for (auto TA : Output.arguments()) {
         if (SemaRef.CheckTemplateArgument(
-                TP, Transformed, F, F->getLocation(), F->getLocation(),
+                TP, TA, F, F->getLocation(), F->getLocation(),
                 /*ArgumentPackIndex=*/-1, CTAI,
                 Sema::CheckTemplateArgumentKind::CTAK_Specified))
           return nullptr;
-        TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
       }
+      // We will substitute the non-deduced template arguments with these
+      // transformed (unpacked at this point) arguments, where that 
substitution
+      // requires a pack for the corresponding parameter packs.
+      TemplateArgsForBuildingFPrime[Index] =
+          TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted);
+    } else {
+      assert(Output.arguments().size() == 1);
+      TemplateArgumentLoc Transformed = Output.arguments()[0];
+      if (SemaRef.CheckTemplateArgument(
+              TP, Transformed, F, F->getLocation(), F->getLocation(),
+              /*ArgumentPackIndex=*/-1, CTAI,
+              Sema::CheckTemplateArgumentKind::CTAK_Specified))
+        return nullptr;
+      TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
     }
   }
 

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

Reply via email to