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/7] 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/7] 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/7] 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/7] 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/7] 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/7] 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
 

>From 8b14146f0100001b07f9f1edc6fc7bf180c0aa4f Mon Sep 17 00:00:00 2001
From: Yanzuo Liu <[email protected]>
Date: Wed, 12 Aug 2026 21:22:41 +0800
Subject: [PATCH 7/7] Use `isa_and_present`

---
 clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 84bd438b6d887..3b0cc39faf6d9 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -937,7 +937,7 @@ class PackDeductionScope {
         unsigned Depth, Index;
 
         // Function parameter packs cannot be deduced.
-        if (isa_and_nonnull<ParmVarDecl>(
+        if (isa_and_present<ParmVarDecl>(
                 dyn_cast<NamedDecl *>(Unexpanded[I].first)))
           continue;
         if (auto DI = getDepthAndIndex(Unexpanded[I]))

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

Reply via email to