MitalAshok created this revision. Herald added a project: All. MitalAshok edited the summary of this revision. MitalAshok added reviewers: rsmith, cor3ntin. MitalAshok published this revision for review. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When instantiating the closure type of a lambda in a template, sometimes a capture which is a pack is not expanded. When that happens, it is replaced with a pack of size 1 containing that pack. Before it is replaced by another instantiation where the pack is expanded, the size is reported to be 1 instead of unknown. This checks if this is happening (i.e., trying to replace a pack declaration with a single declaration that is itself a pack), and not expanding it out in that case. Fixes https://github.com/llvm/llvm-project/issues/63677 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D154716 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/lambda-pack-expansion.cpp Index: clang/test/SemaCXX/lambda-pack-expansion.cpp =================================================================== --- clang/test/SemaCXX/lambda-pack-expansion.cpp +++ clang/test/SemaCXX/lambda-pack-expansion.cpp @@ -21,3 +21,18 @@ take_by_ref(x); } } + +namespace GH63677 { + +template<typename> +void f() { + []<typename... Ts>() -> void { + [...us = Ts{}]{ + (Ts(us), ...); + }; + }.template operator()<int, int>(); +} + +template void f<int>(); + +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ 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(); } Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1270,7 +1270,8 @@ } void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) { - if (Old->isParameterPack()) { + if (Old->isParameterPack() && + (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) { SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old); for (auto *New : NewDecls) SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
Index: clang/test/SemaCXX/lambda-pack-expansion.cpp =================================================================== --- clang/test/SemaCXX/lambda-pack-expansion.cpp +++ clang/test/SemaCXX/lambda-pack-expansion.cpp @@ -21,3 +21,18 @@ take_by_ref(x); } } + +namespace GH63677 { + +template<typename> +void f() { + []<typename... Ts>() -> void { + [...us = Ts{}]{ + (Ts(us), ...); + }; + }.template operator()<int, int>(); +} + +template void f<int>(); + +} Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ 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(); } Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1270,7 +1270,8 @@ } void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) { - if (Old->isParameterPack()) { + if (Old->isParameterPack() && + (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) { SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old); for (auto *New : NewDecls) SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits