https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/215235
>From 2fb93a84edce0012e09c4c633c091f25b96001b0 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Mon, 10 Aug 2026 18:15:58 +0800 Subject: [PATCH 1/6] Handle function parameter packs in `getDepthAndIndex(UnexpandedParameterPack)` --- clang/docs/ReleaseNotes.md | 2 ++ clang/include/clang/Sema/SemaInternal.h | 12 +++++++----- clang/test/SemaTemplate/deduction-crash.cpp | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index fc947d05fad83..75a5afd7a2648 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -445,6 +445,8 @@ features cannot lower the translation-unit ABI level; affect C++26 constexpr structured bindings and expansion statements, but also affects some uses of plain structured bindings. (#GH211930) +- Fixed a crash during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877, GH213760) + #### Bug Fixes to AST Handling - Fixed a non-deterministic ordering of unused local typedefs that made diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 8f6041b5f00e4..58b9ec537b4bd 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -77,11 +77,13 @@ inline std::optional<std::pair<unsigned, unsigned>> getDepthAndIndex(UnexpandedParameterPack UPP) { if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(UPP.first)) return std::make_pair(TTP->getDepth(), TTP->getIndex()); - if (isa<NamedDecl *>(UPP.first)) - return getDepthAndIndex(cast<NamedDecl *>(UPP.first)); - assert((isa<const TemplateSpecializationType *, - const SubstBuiltinTemplatePackType *>(UPP.first))); - return std::nullopt; + if (isa<const TemplateSpecializationType *, + const SubstBuiltinTemplatePackType *>(UPP.first)) + return std::nullopt; + const auto *ND = cast<NamedDecl *>(UPP.first); + if (isa<ParmVarDecl>(ND)) + return std::nullopt; + return getDepthAndIndex(ND); } class TypoCorrectionConsumer : public VisibleDeclConsumer { diff --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp index e7018fd0d8338..2b0befb34a2df 100644 --- a/clang/test/SemaTemplate/deduction-crash.cpp +++ b/clang/test/SemaTemplate/deduction-crash.cpp @@ -177,3 +177,19 @@ namespace GH177545 { template<decltype(auto)()() volatile throw() -> char> // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} struct T2; // expected-error@* {{function cannot return function type 'auto () volatile throw() -> decltype(auto)'}} } + +namespace GH28877 { +template <typename...> struct S; +template <typename... Ts> auto f(Ts... args) -> S<decltype(args)...>; +extern template auto f() -> S<>; +} + +namespace GH46548 { +template <typename... Ts> void a(Ts... args1, char... args2[][sizeof args1]); +extern template void a(); +} + +namespace GH213760 { +template <typename... Ts> void f(Ts... args, decltype(args)...); +void g() { f(); } +} >From 698c3f6f4c553a49d1cc52d6f1a046cc2da32d08 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Mon, 10 Aug 2026 21:27:18 +0800 Subject: [PATCH 2/6] Update ReleaseNotes.md --- clang/docs/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 75a5afd7a2648..5df4bce981b10 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -445,7 +445,7 @@ features cannot lower the translation-unit ABI level; affect C++26 constexpr structured bindings and expansion statements, but also affects some uses of plain structured bindings. (#GH211930) -- Fixed a crash during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877, GH213760) +- Fixed an assertion during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877, GH213760) #### Bug Fixes to AST Handling >From da5a30381810851dd87919b06570fb01cb2222c5 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Tue, 11 Aug 2026 23:24:23 +0800 Subject: [PATCH 3/6] Move the logic to `PackDeductionScope::addPacks` --- clang/include/clang/Sema/SemaInternal.h | 12 +++++------- clang/lib/Sema/SemaTemplateDeduction.cpp | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 58b9ec537b4bd..8f6041b5f00e4 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -77,13 +77,11 @@ inline std::optional<std::pair<unsigned, unsigned>> getDepthAndIndex(UnexpandedParameterPack UPP) { if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(UPP.first)) return std::make_pair(TTP->getDepth(), TTP->getIndex()); - if (isa<const TemplateSpecializationType *, - const SubstBuiltinTemplatePackType *>(UPP.first)) - return std::nullopt; - const auto *ND = cast<NamedDecl *>(UPP.first); - if (isa<ParmVarDecl>(ND)) - return std::nullopt; - return getDepthAndIndex(ND); + if (isa<NamedDecl *>(UPP.first)) + return getDepthAndIndex(cast<NamedDecl *>(UPP.first)); + assert((isa<const TemplateSpecializationType *, + const SubstBuiltinTemplatePackType *>(UPP.first))); + return std::nullopt; } class TypoCorrectionConsumer : public VisibleDeclConsumer { diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 3c45806c47a6e..e0fbade55f4e5 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -907,6 +907,21 @@ class PackDeductionScope { llvm::SmallBitVector SawIndices(TemplateParams->size()); llvm::SmallVector<TemplateArgument, 4> ExtraDeductions; + // This is basically clang::getDepthAndIndex but this also handles function + // parameter packs. + auto GetDepthAndIndex = [](UnexpandedParameterPack UPP) + -> std::optional<std::pair<unsigned, unsigned>> { + if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(UPP.first)) + return std::make_pair(TTP->getDepth(), TTP->getIndex()); + if (isa<const TemplateSpecializationType *, + const SubstBuiltinTemplatePackType *>(UPP.first)) + return std::nullopt; + const auto *ND = cast<NamedDecl *>(UPP.first); + if (isa<ParmVarDecl>(ND)) + return std::nullopt; + return getDepthAndIndex(ND); + }; + auto AddPack = [&](unsigned Index) { if (SawIndices[Index]) return; @@ -935,7 +950,7 @@ class PackDeductionScope { S.collectUnexpandedParameterPacks(Pattern, Unexpanded); for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { unsigned Depth, Index; - if (auto DI = getDepthAndIndex(Unexpanded[I])) + if (auto DI = GetDepthAndIndex(Unexpanded[I])) std::tie(Depth, Index) = *DI; else continue; >From 8bb76365cfe63b63e282dd6d032e05e215feb8f2 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Wed, 12 Aug 2026 11:32:29 +0800 Subject: [PATCH 4/6] Check for function parameter packs instead of implementing a `GetDepthAndIndex`. --- clang/lib/Sema/SemaTemplateDeduction.cpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e0fbade55f4e5..84bd438b6d887 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -907,21 +907,6 @@ class PackDeductionScope { llvm::SmallBitVector SawIndices(TemplateParams->size()); llvm::SmallVector<TemplateArgument, 4> ExtraDeductions; - // This is basically clang::getDepthAndIndex but this also handles function - // parameter packs. - auto GetDepthAndIndex = [](UnexpandedParameterPack UPP) - -> std::optional<std::pair<unsigned, unsigned>> { - if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(UPP.first)) - return std::make_pair(TTP->getDepth(), TTP->getIndex()); - if (isa<const TemplateSpecializationType *, - const SubstBuiltinTemplatePackType *>(UPP.first)) - return std::nullopt; - const auto *ND = cast<NamedDecl *>(UPP.first); - if (isa<ParmVarDecl>(ND)) - return std::nullopt; - return getDepthAndIndex(ND); - }; - auto AddPack = [&](unsigned Index) { if (SawIndices[Index]) return; @@ -950,7 +935,12 @@ class PackDeductionScope { S.collectUnexpandedParameterPacks(Pattern, Unexpanded); for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { unsigned Depth, Index; - if (auto DI = GetDepthAndIndex(Unexpanded[I])) + + // Function parameter packs cannot be deduced. + if (isa_and_nonnull<ParmVarDecl>( + dyn_cast<NamedDecl *>(Unexpanded[I].first))) + continue; + if (auto DI = getDepthAndIndex(Unexpanded[I])) std::tie(Depth, Index) = *DI; else continue; >From 2d99e9c2375047de58f9a98eccda2d1b3ab526b3 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Wed, 12 Aug 2026 13:23:12 +0800 Subject: [PATCH 5/6] Fix release note and add tests --- clang/docs/ReleaseNotes.md | 2 +- clang/test/SemaTemplate/deduction-crash.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 5df4bce981b10..7338048aa50d0 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -445,7 +445,7 @@ features cannot lower the translation-unit ABI level; affect C++26 constexpr structured bindings and expansion statements, but also affects some uses of plain structured bindings. (#GH211930) -- Fixed an assertion during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877, GH213760) +- Fixed an assertion during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877), (GH213760) #### Bug Fixes to AST Handling diff --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp index 2b0befb34a2df..8b6142745ac3a 100644 --- a/clang/test/SemaTemplate/deduction-crash.cpp +++ b/clang/test/SemaTemplate/deduction-crash.cpp @@ -190,6 +190,15 @@ extern template void a(); } namespace GH213760 { -template <typename... Ts> void f(Ts... args, decltype(args)...); -void g() { f(); } +template <typename... Ts> void f(Ts... args, decltype(args)...); // #GH213760-f +void g() { + f(); + f<int>(1, 2); + f(1, 2); + // expected-error@-1 {{no matching function for call to 'f'}} + // expected-note@#GH213760-f {{candidate function [with Ts = <>] not viable: requires 0 arguments, but 2 were provided}} + f<int, int>(1, 2); + // expected-error@-1 {{no matching function for call to 'f'}} + // expected-note@#GH213760-f {{candidate function [with Ts = <int, int>] not viable: requires 4 arguments, but 2 were provided}} +} } >From 5d8d56078ca2ca9a752498fa931d87f1b76294d1 Mon Sep 17 00:00:00 2001 From: Yanzuo Liu <[email protected]> Date: Wed, 12 Aug 2026 14:17:19 +0800 Subject: [PATCH 6/6] Fix release note (2nd attempt) --- clang/docs/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 7338048aa50d0..d0a9afe77349f 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -445,7 +445,7 @@ features cannot lower the translation-unit ABI level; affect C++26 constexpr structured bindings and expansion statements, but also affects some uses of plain structured bindings. (#GH211930) -- Fixed an assertion during template argument deduction where a function parameter pack is referenced by other types in the function type. (GH28877), (GH213760) +- Fixed an assertion during template argument deduction where a function parameter pack is referenced by other types in the function type. (#GH28877), (#GH213760) #### Bug Fixes to AST Handling _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
