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 <[email protected]> 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@-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@-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 <[email protected]> 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; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
