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

dependent pack expansions in __type_pack_element can result in single-element 
template argument lists. When performing semantic analysis for these builtins, 
the compiler needs to account for the dependent expansions and handle them 
without triggering strict size assertions. The patch adds this analysis and 
ensures we either defer evaluation for dependent cases or report clear 
out-of-bounds diagnostics instead of crashing

fixes #180307

>From f8db0eecec11972bca0241d6c58781d4b525fe13 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Sun, 8 Feb 2026 17:40:06 +0530
Subject: [PATCH] [clang][Sema] Fix crash on __type_pack_element with dependent
 packs (GH180307)

Ensure __type_pack_element handles cases where Converted.size() is 1, which can 
happen with dependent pack expansions or missing arguments. Instead of 
asserting, emit an out-of-bounds error for the missing pack case and return 
QualType() for the dependent case.
---
 clang/lib/Sema/SemaTemplate.cpp          | 20 ++++++++++++++++----
 clang/test/SemaCXX/type_pack_element.cpp |  5 +++++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3497ff7856eed..5496cd766adb8 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3462,16 +3462,28 @@ static QualType checkBuiltinTemplateIdType(
     // 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");
+    assert((Converted.size() == 1 || 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())
+    TemplateArgument IndexArg = Converted[0];
+    if (IndexArg.isDependent())
       return QualType();
 
     llvm::APSInt Index = IndexArg.getAsIntegral();
     assert(Index >= 0 && "the index used with __type_pack_element should be of 
"
                          "type std::size_t, and hence be non-negative");
+
+    // If the pack is empty, we only have the index argument.
+    if (Converted.size() == 1) {
+      SemaRef.Diag(TemplateArgs[0].getLocation(),
+                   diag::err_type_pack_element_out_of_bounds);
+      return QualType();
+    }
+
+    TemplateArgument Ts = Converted[1];
+    if (Ts.isDependent())
+      return QualType();
+
     // If the Index is out of bounds, the program is ill-formed.
     if (Index >= Ts.pack_size()) {
       SemaRef.Diag(TemplateArgs[0].getLocation(),
diff --git a/clang/test/SemaCXX/type_pack_element.cpp 
b/clang/test/SemaCXX/type_pack_element.cpp
index d22d5fa2ba67c..1ac5c861c18e8 100644
--- a/clang/test/SemaCXX/type_pack_element.cpp
+++ b/clang/test/SemaCXX/type_pack_element.cpp
@@ -43,3 +43,8 @@ static_assert(__is_same(__type_pack_element<5, X<0>, X<1>, 
X<2>, X<3>, X<4>, X<5
 template <SizeT Index, typename ...T>
 using ErrorTypePackElement1 = __type_pack_element<Index, T...>; // 
expected-error{{may not be accessed at an out of bounds index}}
 using illformed1 = ErrorTypePackElement1<3, X<0>, X<1>>;  // expected-note{{in 
instantiation}}
+
+template <SizeT... Seq>
+void gh180307(__type_pack_element<Seq...>) {}
+
+using gh180307_empty = __type_pack_element<0>; // expected-error {{a parameter 
pack may not be accessed at an out of bounds index}}

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

Reply via email to