https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/180407

>From cf731e642abeece29ee5f397123b28a84bd2a428 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sun, 8 Feb 2026 17:40:06 +0530
Subject: [PATCH 1/4] [clang][sema] fix crash on builtin template ids with
 dependent packs (gh180307)

---
 clang/lib/Sema/SemaTemplate.cpp               | 28 ++++++-------
 .../builtin_templates_invalid_parameters.cpp  | 41 +++++++++++++++++++
 2 files changed, 53 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3497ff7856eed..c54392418e25e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3406,10 +3406,22 @@ static QualType checkBuiltinTemplateIdType(
     Sema &SemaRef, ElaboratedTypeKeyword Keyword, BuiltinTemplateDecl *BTD,
     ArrayRef<TemplateArgument> Converted, SourceLocation TemplateLoc,
     TemplateArgumentListInfo &TemplateArgs) {
+  TemplateParameterList *Params = BTD->getTemplateParameters();
+  unsigned RequiredArgs = Params->size();
+  if (Params->hasParameterPack()) {
+    if (Converted.size() < RequiredArgs)
+      return QualType();
+  } else {
+    if (Converted.size() != RequiredArgs)
+      return QualType();
+  }
+
   ASTContext &Context = SemaRef.getASTContext();
 
   switch (BTD->getBuiltinTemplateKind()) {
   case BTK__make_integer_seq: {
+    if (Converted[2].isDependent())
+      return QualType();
     // Specializations of __make_integer_seq<S, T, N> are treated like
     // S<T, 0, ..., N-1>.
 
@@ -3423,8 +3435,6 @@ static QualType checkBuiltinTemplateIdType(
     }
 
     TemplateArgument NumArgsArg = Converted[2];
-    if (NumArgsArg.isDependent())
-      return QualType();
 
     TemplateArgumentListInfo SyntheticTemplateArgs;
     // The type argument, wrapped in substitution sugar, gets reused as the
@@ -3459,12 +3469,6 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__type_pack_element: {
-    // Specializations of
-    //    __type_pack_element<Index, T_1, ..., T_N>
-    // are treated like T_Index.
-    assert(Converted.size() == 2 &&
-           "__type_pack_element should be given an index and a parameter 
pack");
-
     TemplateArgument IndexArg = Converted[0], Ts = Converted[1];
     if (IndexArg.isDependent() || Ts.isDependent())
       return QualType();
@@ -3485,7 +3489,6 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__builtin_common_type: {
-    assert(Converted.size() == 4);
     if (llvm::any_of(Converted, [](auto &C) { return C.isDependent(); }))
       return QualType();
 
@@ -3508,8 +3511,6 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__hlsl_spirv_type: {
-    assert(Converted.size() == 4);
-
     if (!Context.getTargetInfo().getTriple().isSPIRV()) {
       SemaRef.Diag(TemplateLoc, diag::err_hlsl_spirv_only) << BTD;
     }
@@ -3537,12 +3538,7 @@ static QualType checkBuiltinTemplateIdType(
     return Context.getHLSLInlineSpirvType(Opcode, Size, Alignment, Operands);
   }
   case BTK__builtin_dedup_pack: {
-    assert(Converted.size() == 1 && "__builtin_dedup_pack should be given "
-                                    "a parameter pack");
     TemplateArgument Ts = Converted[0];
-    // Delay the computation until we can compute the final result. We choose
-    // not to remove the duplicates upfront before substitution to keep the 
code
-    // simple.
     if (Ts.isDependent())
       return QualType();
     assert(Ts.getKind() == clang::TemplateArgument::Pack);
diff --git a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp 
b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
new file mode 100644
index 0000000000000..dd74bbd1d900d
--- /dev/null
+++ b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-error@* 2 {{template argument for non-type template parameter must 
be an expression}}
+
+using SizeT = decltype(sizeof(int));
+
+// Dependent cases that previously crashed but now return QualType() 
gracefully.
+template <SizeT... Seq> // expected-note {{template parameter is declared 
here}}
+using gh180307 = __type_pack_element<Seq...>;
+
+template <typename T>
+using gh180307_bis = __make_integer_seq<gh180307, T>;
+// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
+
+// Eager expansion checks: Built-in templates should expand even if the
+// destination template OR the type argument is dependent, provided the size 
is known.
+template <template <typename T, T... Ints> class Seq>
+using test_make_integer_seq_eager = __make_integer_seq<Seq, int, 2>;
+
+template <typename T, T... Ints> struct MySeq;
+using check_eager = test_make_integer_seq_eager<MySeq>;
+using check_eager = MySeq<int, 0, 1>;
+
+template <typename T>
+using test_make_integer_seq_type_dependent = __make_integer_seq<MySeq, T, 2>;
+using check_type_eager = test_make_integer_seq_type_dependent<int>;
+using check_type_eager = MySeq<int, 0, 1>;
+
+// Too many arguments tests
+template <int N> struct S; // expected-note {{template parameter is declared 
here}}
+using too_many_args = __make_integer_seq<S, int, 10, int>; 
+// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
+
+// Too few arguments tests
+template <SizeT Index>
+using too_few_args = __type_pack_element<Index>;
+
+// Verify that too_few_args doesn't crash on instantiation either
+// (It should just be an invalid type)
+template <SizeT I> struct Wrap {
+  using type = too_few_args<I>;
+};

>From 533718dd5cdc35aefed75eeee5f6a0dafe030069 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sun, 22 Feb 2026 19:07:35 +0530
Subject: [PATCH 2/4] [clang] address reviewer feedback

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +-
 clang/lib/Sema/SemaTemplate.cpp               | 27 +++++++++++--------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f999c362307af..d75ca7a933e6e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6099,7 +6099,7 @@ def note_template_declared_here : Note<
   "%1 declared here">;
 def err_template_expansion_into_fixed_list : Error<
   "pack expansion used as argument for non-pack parameter of %select{alias "
-  "template|concept}0">;
+  "template|concept|builtin template}0">;
 def note_parameter_type : Note<
   "parameter of type %0 is declared here">;
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c54392418e25e..f094fcbd51dfd 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3408,20 +3408,19 @@ static QualType checkBuiltinTemplateIdType(
     TemplateArgumentListInfo &TemplateArgs) {
   TemplateParameterList *Params = BTD->getTemplateParameters();
   unsigned RequiredArgs = Params->size();
-  if (Params->hasParameterPack()) {
-    if (Converted.size() < RequiredArgs)
-      return QualType();
-  } else {
-    if (Converted.size() != RequiredArgs)
-      return QualType();
+
+  if (Converted.size() != RequiredArgs) {
+    // If we have a different number of arguments than parameters, it's either
+    // an error or we have a dependent pack expansion that hasn't been expanded
+    // and partitioned yet. In either case, we can't proceed with 
instantiation,
+    // so we return an empty QualType (staying dependent or signaling an 
error).
+    return QualType();
   }
 
   ASTContext &Context = SemaRef.getASTContext();
 
   switch (BTD->getBuiltinTemplateKind()) {
   case BTK__make_integer_seq: {
-    if (Converted[2].isDependent())
-      return QualType();
     // Specializations of __make_integer_seq<S, T, N> are treated like
     // S<T, 0, ..., N-1>.
 
@@ -3435,6 +3434,9 @@ static QualType checkBuiltinTemplateIdType(
     }
 
     TemplateArgument NumArgsArg = Converted[2];
+    if (NumArgsArg.isDependent())
+      return QualType();
+
 
     TemplateArgumentListInfo SyntheticTemplateArgs;
     // The type argument, wrapped in substitution sugar, gets reused as the
@@ -5979,11 +5981,14 @@ bool Sema::CheckTemplateArgumentList(
           // CWG1430/CWG2686: we have a pack expansion as an argument to an
           // alias template or concept, and it's not part of a parameter pack.
           // This can't be canonicalized, so reject it now.
-          if (isa<TypeAliasTemplateDecl, ConceptDecl>(Template)) {
+          if (isa<TypeAliasTemplateDecl, ConceptDecl, BuiltinTemplateDecl>(
+                  Template)) {
+            unsigned DiagSelect = isa<ConceptDecl>(Template)           ? 1
+                                  : isa<BuiltinTemplateDecl>(Template) ? 2
+                                                                       : 0;
             Diag(ArgLoc.getLocation(),
                  diag::err_template_expansion_into_fixed_list)
-                << (isa<ConceptDecl>(Template) ? 1 : 0)
-                << ArgLoc.getSourceRange();
+                << DiagSelect << ArgLoc.getSourceRange();
             NoteTemplateParameterLocation(**Param);
             return true;
           }

>From dd2bdf9176cb34a08a92e8f4d70367291d71a866 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sun, 1 Mar 2026 02:15:01 +0530
Subject: [PATCH 3/4] address reviewer feedbacks

---
 clang/lib/Sema/SemaTemplate.cpp               | 33 +++++++++++--------
 .../builtin_templates_invalid_parameters.cpp  |  7 ++--
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index f094fcbd51dfd..c5cb3199c0b6c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3406,19 +3406,11 @@ static QualType checkBuiltinTemplateIdType(
     Sema &SemaRef, ElaboratedTypeKeyword Keyword, BuiltinTemplateDecl *BTD,
     ArrayRef<TemplateArgument> Converted, SourceLocation TemplateLoc,
     TemplateArgumentListInfo &TemplateArgs) {
-  TemplateParameterList *Params = BTD->getTemplateParameters();
-  unsigned RequiredArgs = Params->size();
-
-  if (Converted.size() != RequiredArgs) {
-    // If we have a different number of arguments than parameters, it's either
-    // an error or we have a dependent pack expansion that hasn't been expanded
-    // and partitioned yet. In either case, we can't proceed with 
instantiation,
-    // so we return an empty QualType (staying dependent or signaling an 
error).
-    return QualType();
-  }
-
   ASTContext &Context = SemaRef.getASTContext();
 
+  assert(Converted.size() == BTD->getTemplateParameters()->size() &&
+         "Builtin template arguments do not match its parameters");
+
   switch (BTD->getBuiltinTemplateKind()) {
   case BTK__make_integer_seq: {
     // Specializations of __make_integer_seq<S, T, N> are treated like
@@ -3437,7 +3429,6 @@ static QualType checkBuiltinTemplateIdType(
     if (NumArgsArg.isDependent())
       return QualType();
 
-
     TemplateArgumentListInfo SyntheticTemplateArgs;
     // The type argument, wrapped in substitution sugar, gets reused as the
     // first template argument in the synthetic template argument list.
@@ -3471,6 +3462,12 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__type_pack_element: {
+    // Specializations of
+    //    __type_pack_element<Index, T_1, ..., T_N>
+    // are treated like T_Index.
+    assert(Converted.size() == 2 &&
+           "__type_pack_element should be given an index and a parameter 
pack");
+
     TemplateArgument IndexArg = Converted[0], Ts = Converted[1];
     if (IndexArg.isDependent() || Ts.isDependent())
       return QualType();
@@ -3491,6 +3488,7 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__builtin_common_type: {
+    assert(Converted.size() == 4);
     if (llvm::any_of(Converted, [](auto &C) { return C.isDependent(); }))
       return QualType();
 
@@ -3513,6 +3511,8 @@ static QualType checkBuiltinTemplateIdType(
   }
 
   case BTK__hlsl_spirv_type: {
+    assert(Converted.size() == 4);
+
     if (!Context.getTargetInfo().getTriple().isSPIRV()) {
       SemaRef.Diag(TemplateLoc, diag::err_hlsl_spirv_only) << BTD;
     }
@@ -3540,7 +3540,12 @@ static QualType checkBuiltinTemplateIdType(
     return Context.getHLSLInlineSpirvType(Opcode, Size, Alignment, Operands);
   }
   case BTK__builtin_dedup_pack: {
+    assert(Converted.size() == 1 && "__builtin_dedup_pack should be given "
+                                    "a parameter pack");
     TemplateArgument Ts = Converted[0];
+    // Delay the computation until we can compute the final result. We choose
+    // not to remove the duplicates upfront before substitution to keep the 
code
+    // simple.
     if (Ts.isDependent())
       return QualType();
     assert(Ts.getKind() == clang::TemplateArgument::Pack);
@@ -5979,8 +5984,8 @@ bool Sema::CheckTemplateArgumentList(
                                                 Params->getDepth()));
         if (ArgIsExpansion && NonPackParameter) {
           // CWG1430/CWG2686: we have a pack expansion as an argument to an
-          // alias template or concept, and it's not part of a parameter pack.
-          // This can't be canonicalized, so reject it now.
+          // alias template, builtin template, or concept, and it's not part of
+          // a parameter pack. This can't be canonicalized, so reject it now.
           if (isa<TypeAliasTemplateDecl, ConceptDecl, BuiltinTemplateDecl>(
                   Template)) {
             unsigned DiagSelect = isa<ConceptDecl>(Template)           ? 1
diff --git a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp 
b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
index dd74bbd1d900d..dfd5d9191422b 100644
--- a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
+++ b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
@@ -1,15 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 // expected-error@* 2 {{template argument for non-type template parameter must 
be an expression}}
+// expected-note@* 2 {{template template argument has different template 
parameters than its corresponding template template parameter}}
 
 using SizeT = decltype(sizeof(int));
 
 // Dependent cases that previously crashed but now return QualType() 
gracefully.
 template <SizeT... Seq> // expected-note {{template parameter is declared 
here}}
-using gh180307 = __type_pack_element<Seq...>;
+using gh180307 = __type_pack_element<Seq...>; // expected-error {{pack 
expansion used as argument for non-pack parameter of builtin template}}
 
 template <typename T>
 using gh180307_bis = __make_integer_seq<gh180307, T>;
-// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
 
 // Eager expansion checks: Built-in templates should expand even if the
 // destination template OR the type argument is dependent, provided the size 
is known.
@@ -27,8 +27,7 @@ using check_type_eager = MySeq<int, 0, 1>;
 
 // Too many arguments tests
 template <int N> struct S; // expected-note {{template parameter is declared 
here}}
-using too_many_args = __make_integer_seq<S, int, 10, int>; 
-// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
+using too_many_args = __make_integer_seq<S, int, 10, int>;
 
 // Too few arguments tests
 template <SizeT Index>

>From 46cf543beae8bf797abdc0076fd50381b346ca64 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sun, 1 Mar 2026 03:38:04 +0530
Subject: [PATCH 4/4] Address reviewer feedback: correctly apply
 BuiltinTemplateDecl fixes and align tests

---
 .../test/SemaCXX/builtin_templates_invalid_parameters.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp 
b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
index dfd5d9191422b..6ba917f5c4b8b 100644
--- a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
+++ b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp
@@ -1,6 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-error@* 2 {{template argument for non-type template parameter must 
be an expression}}
-// expected-note@* 2 {{template template argument has different template 
parameters than its corresponding template template parameter}}
 
 using SizeT = decltype(sizeof(int));
 
@@ -10,6 +8,8 @@ using gh180307 = __type_pack_element<Seq...>; // 
expected-error {{pack expansion
 
 template <typename T>
 using gh180307_bis = __make_integer_seq<gh180307, T>;
+// expected-error@-1 {{template argument for non-type template parameter must 
be an expression}}
+// expected-note@-2 {{template template argument has different template 
parameters than its corresponding template template parameter}}
 
 // Eager expansion checks: Built-in templates should expand even if the
 // destination template OR the type argument is dependent, provided the size 
is known.
@@ -27,7 +27,9 @@ using check_type_eager = MySeq<int, 0, 1>;
 
 // Too many arguments tests
 template <int N> struct S; // expected-note {{template parameter is declared 
here}}
-using too_many_args = __make_integer_seq<S, int, 10, int>;
+using too_many_args = __make_integer_seq<S, int, 2, int>;
+// expected-error@-1 {{template argument for non-type template parameter must 
be an expression}}
+// expected-note@-2 {{template template argument has different template 
parameters than its corresponding template template parameter}}
 
 // Too few arguments tests
 template <SizeT Index>

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

Reply via email to