[clang] [clang] Treat pack-index-specifiers as non-deduced contexts (PR #232883)
Nikolai Fedotenko via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 17 14:53:31 PDT 2026
https://github.com/nfedotenko updated https://github.com/llvm/llvm-project/pull/232883
>From a45a15049a86689199e8580e110aaaee11678efe Mon Sep 17 00:00:00 2001
From: Nikolay Fedotenko <kalkolay at protonmail.com>
Date: Fri, 16 Oct 2026 22:06:46 +0400
Subject: [PATCH 1/2] [clang] Treat pack-index-specifiers as non-deduced
contexts
Per C++26 [temp.deduct.type]p5.2, a pack-index-specifier is a non-deduced context. Deduction against an unresolved PackIndexingType used to fail with a bare IncompletePack result that carried no parameter/argument info, so matching an explicit instantiation, explicit specialization, or address-of against such a function template was rejected, and emitting the resulting diagnostic crashed in DiagnoseBadDeduction (assertion "no parameter found for incomplete deduction result" in +asserts builds, null dereference otherwise).
A pack-index-specifier whose pack and index are fully substituted canonicalizes to its selected type, so the PackIndexing case in DeduceTemplateArgumentsByTypeMatch only ever sees unresolved ones; returning Success there (deducing nothing) is all that is needed.
Fixes #232220
---
clang/docs/ReleaseNotes.md | 6 +++++
clang/lib/Sema/SemaTemplateDeduction.cpp | 20 ++++++++---------
clang/test/SemaCXX/cxx2c-pack-indexing.cpp | 26 ++++++++++++++++++++++
3 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7d3f0eb702553d..7705b0e61bf4bf 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -1024,6 +1024,12 @@ features cannot lower the translation-unit ABI level;
- Fixed an issue where Clang would allow invoking consteval functions outside
of a manifestly constant evaluated context. (#GH183415, #GH169139)
+- A pack-index-specifier (`T...[N]`) is now treated as a non-deduced context,
+ per C++26 [temp.deduct.type]. This fixes a crash when matching an explicit
+ instantiation, explicit specialization, or call against a function template
+ whose parameter type uses pack indexing, and makes such valid matches
+ succeed instead of being rejected. (#GH232220)
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 90724e1d01cb20..da3ac0100f62ac 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2556,16 +2556,16 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
// No template argument deduction for these types
return TemplateDeductionResult::Success;
- case Type::PackIndexing: {
- const PackIndexingType *PIT = P->getAs<PackIndexingType>();
- if (PIT->hasSelectedType()) {
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, PIT->getSelectedType(), A, Info, Deduced, TDF,
- degradeCallPartialOrderingKind(POK),
- /*DeducedFromArrayBound=*/false, HasDeducedAnyParam);
- }
- return TemplateDeductionResult::IncompletePack;
- }
+ case Type::PackIndexing:
+ // C++26 [temp.deduct.type]p5.2:
+ // The non-deduced contexts are:
+ // [...]
+ // - A pack-index-specifier or a pack-index-expression.
+ //
+ // A pack-index-specifier whose index and pack are fully substituted
+ // canonicalizes to its selected type, so this case is only reached for
+ // an unresolved one; nothing can be deduced from it.
+ return TemplateDeductionResult::Success;
}
llvm_unreachable("Invalid Type Class!");
diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
index bbd708d3b63f52..910160dbf683d9 100644
--- a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
+++ b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
@@ -378,3 +378,29 @@ int test(){
}
}
+
+namespace GH232220 {
+template <class... T> void f(T...[1]); // #GH232220-f
+template <class... T> void g(T...[1]) {}
+
+// T...[1] is a non-deduced context ([temp.deduct.type]p5.2); matching a
+// specialization against the template used to fail and then crash while
+// emitting the resulting diagnostic.
+template void g<int, short>(short);
+
+template <class... T> void h(T...[1]);
+template <> void h<int, short>(short) {}
+
+void test() {
+ f<int, short>(short{});
+ void (*p)(short) = f<int, short>;
+ g<int, long>(42L);
+
+ f(0);
+ // expected-error at -1 {{no matching function for call to 'f'}}
+ // expected-note@#GH232220-f {{candidate template ignored: substitution failure [with T = <>]: invalid index 1 for pack 'T' of size 0}}
+ f<int>(0);
+ // expected-error at -1 {{no matching function for call to 'f'}}
+ // expected-note@#GH232220-f {{candidate template ignored: substitution failure [with T = <int>]: invalid index 1 for pack 'T' of size 1}}
+}
+} // namespace GH232220
>From c1eeb66e6da08a0eb6b953a6dcbe7b6a9146f55b Mon Sep 17 00:00:00 2001
From: Nikolay Fedotenko <kalkolay at protonmail.com>
Date: Sun, 18 Oct 2026 01:53:09 +0400
Subject: [PATCH 2/2] Assert that a canonical pack-index-specifier has no
selected type
---
clang/lib/Sema/SemaTemplateDeduction.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index da3ac0100f62ac..b9cda516c7a486 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2561,10 +2561,9 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
// The non-deduced contexts are:
// [...]
// - A pack-index-specifier or a pack-index-expression.
- //
- // A pack-index-specifier whose index and pack are fully substituted
- // canonicalizes to its selected type, so this case is only reached for
- // an unresolved one; nothing can be deduced from it.
+ assert(!P->getAs<PackIndexingType>()->hasSelectedType() &&
+ "a pack-index-specifier with a selected type canonicalizes to "
+ "the selected type and should not dispatch here");
return TemplateDeductionResult::Success;
}
More information about the cfe-commits
mailing list