[PATCH] D154716: [SemaCXX] Fix bug where unexpanded lambda captures where assumed to be expanded

Mital Ashok via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 7 06:54:13 PDT 2023


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(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154716.538125.patch
Type: text/x-patch
Size: 2153 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230707/00299795/attachment.bin>


More information about the cfe-commits mailing list