diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1270,7 +1270,8 @@ } void transformedLocalDecl(Decl *Old, ArrayRef NewDecls) { - if (Old->isParameterPack()) { + if (Old->isParameterPack() && + (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) { SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old); for (auto *New : NewDecls) SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg( diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13340,14 +13340,14 @@ OldVD->getInit()->getSourceRange(), Unexpanded, Expand, RetainExpansion, NumExpansions)) return ExprError(); + assert(!RetainExpansion && "Should not need to retain expansion after a " + "capture since it cannot be extended"); if (Expand) { for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); SubstInitCapture(SourceLocation(), std::nullopt); } - } - if (!Expand || RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); + } else { SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions); Result.EllipsisLoc = ExpansionTL.getEllipsisLoc(); } diff --git a/clang/test/SemaCXX/lambda-pack-expansion.cpp b/clang/test/SemaCXX/lambda-pack-expansion.cpp --- a/clang/test/SemaCXX/lambda-pack-expansion.cpp +++ b/clang/test/SemaCXX/lambda-pack-expansion.cpp @@ -21,3 +21,18 @@ take_by_ref(x); } } + +namespace GH63677 { + +template +void f() { + []() -> void { + [...us = Ts{}]{ + (Ts(us), ...); + }; + }.template operator()(); +} + +template void f(); + +}