r362375 - Revert rL362358 : PR42104: Support instantiations of lambdas that implicitly capture packs.

Simon Pilgrim via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 3 02:56:09 PDT 2019


Author: rksimon
Date: Mon Jun  3 02:56:09 2019
New Revision: 362375

URL: http://llvm.org/viewvc/llvm-project?rev=362375&view=rev
Log:
Revert rL362358 : PR42104: Support instantiations of lambdas that implicitly capture packs.

Two changes:
 * Track odr-use via FunctionParmPackExprs to properly handle dependent
   odr-uses of packs in generic lambdas.
 * Do not instantiate implicit captures; instead, regenerate them by
   instantiating the body of the lambda. This is necessary to
   distinguish between cases where only one element of a pack is
   captured and cases where the entire pack is captured.
........
Fixes http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win buildbot failures

Removed:
    cfe/trunk/test/SemaTemplate/lambda-capture-pack.cpp
Modified:
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/ScopeInfo.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Mon Jun  3 02:56:09 2019
@@ -15,7 +15,6 @@
 #define LLVM_CLANG_SEMA_SCOPEINFO_H
 
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/CapturedStmt.h"
 #include "clang/Basic/LLVM.h"
@@ -914,8 +913,7 @@ public:
   ///   };
   /// }
   void addPotentialCapture(Expr *VarExpr) {
-    assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) ||
-           isa<FunctionParmPackExpr>(VarExpr));
+    assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
     PotentiallyCapturingExprs.push_back(VarExpr);
   }
 
@@ -967,15 +965,13 @@ public:
   ///  building such a node. So we need a rule that anyone can implement and get
   ///  exactly the same result".
   void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
-    assert(isa<DeclRefExpr>(CapturingVarExpr) ||
-           isa<MemberExpr>(CapturingVarExpr) ||
-           isa<FunctionParmPackExpr>(CapturingVarExpr));
+    assert(isa<DeclRefExpr>(CapturingVarExpr)
+        || isa<MemberExpr>(CapturingVarExpr));
     NonODRUsedCapturingExprs.insert(CapturingVarExpr);
   }
   bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
-    assert(isa<DeclRefExpr>(CapturingVarExpr) ||
-           isa<MemberExpr>(CapturingVarExpr) ||
-           isa<FunctionParmPackExpr>(CapturingVarExpr));
+    assert(isa<DeclRefExpr>(CapturingVarExpr)
+      || isa<MemberExpr>(CapturingVarExpr));
     return NonODRUsedCapturingExprs.count(CapturingVarExpr);
   }
   void removePotentialCapture(Expr *E) {
@@ -997,8 +993,9 @@ public:
                                   PotentialThisCaptureLocation.isValid();
   }
 
-  void visitPotentialCaptures(
-      llvm::function_ref<void(VarDecl *, Expr *)> Callback) const;
+  // When passed the index, returns the VarDecl and Expr associated
+  // with the index.
+  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
 };
 
 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun  3 02:56:09 2019
@@ -4179,7 +4179,6 @@ public:
   void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
   void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr);
   void MarkMemberReferenced(MemberExpr *E);
-  void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E);
   void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc,
                                          unsigned CapturingScopeIndex);
 

Modified: cfe/trunk/lib/Sema/ScopeInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ScopeInfo.cpp?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/ScopeInfo.cpp (original)
+++ cfe/trunk/lib/Sema/ScopeInfo.cpp Mon Jun  3 02:56:09 2019
@@ -229,20 +229,20 @@ bool CapturingScopeInfo::isVLATypeCaptur
   return false;
 }
 
-void LambdaScopeInfo::visitPotentialCaptures(
-    llvm::function_ref<void(VarDecl *, Expr *)> Callback) const {
-  for (Expr *E : PotentiallyCapturingExprs) {
-    if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
-      Callback(cast<VarDecl>(DRE->getFoundDecl()), E);
-    } else if (auto *ME = dyn_cast<MemberExpr>(E)) {
-      Callback(cast<VarDecl>(ME->getMemberDecl()), E);
-    } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {
-      for (VarDecl *VD : *FP)
-        Callback(VD, E);
-    } else {
-      llvm_unreachable("unexpected expression in potential captures list");
-    }
-  }
+void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
+                                                  Expr *&E) const {
+  assert(Idx < getNumPotentialVariableCaptures() &&
+         "Index of potential capture must be within 0 to less than the "
+         "number of captures!");
+  E = PotentiallyCapturingExprs[Idx];
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
+  else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    VD = dyn_cast<VarDecl>(ME->getMemberDecl());
+  else
+    llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
+    "potential captures");
+  assert(VD);
 }
 
 FunctionScopeInfo::~FunctionScopeInfo() { }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun  3 02:56:09 2019
@@ -14610,9 +14610,7 @@ namespace {
     // context so never needs to be transformed.
     // FIXME: Ideally we wouldn't transform the closure type either, and would
     // just recreate the capture expressions and lambda expression.
-    StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
-      return SkipLambdaBody(E, Body);
-    }
+    StmtResult TransformLambdaBody(Stmt *Body) { return Body; }
   };
 }
 
@@ -15056,7 +15054,7 @@ void Sema::MarkFunctionReferenced(Source
 ///    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
 static void
 MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef,
-                   const unsigned *const FunctionScopeIndexToStopAt = nullptr) {
+                   const unsigned *const FunctionScopeIndexToStopAt) {
   // Keep track of used but undefined variables.
   // FIXME: We shouldn't suppress this warning for static data members.
   if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
@@ -15737,19 +15735,14 @@ void Sema::UpdateMarkingForLValueToRValu
   // variable.
   if (LambdaScopeInfo *LSI = getCurLambda()) {
     Expr *SansParensExpr = E->IgnoreParens();
-    VarDecl *Var;
-    ArrayRef<VarDecl *> Vars = None;
+    VarDecl *Var = nullptr;
     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr))
-      Vars = Var = dyn_cast<VarDecl>(DRE->getFoundDecl());
+      Var = dyn_cast<VarDecl>(DRE->getFoundDecl());
     else if (MemberExpr *ME = dyn_cast<MemberExpr>(SansParensExpr))
-      Vars = Var = dyn_cast<VarDecl>(ME->getMemberDecl());
-    else if (auto *FPPE = dyn_cast<FunctionParmPackExpr>(SansParensExpr))
-      Vars = llvm::makeArrayRef(FPPE->begin(), FPPE->end());
-
-    for (VarDecl *VD : Vars) {
-      if (Var && IsVariableNonDependentAndAConstantExpression(VD, Context))
-        LSI->markVariableExprAsNonODRUsed(SansParensExpr);
-    }
+      Var = dyn_cast<VarDecl>(ME->getMemberDecl());
+
+    if (Var && IsVariableNonDependentAndAConstantExpression(Var, Context))
+      LSI->markVariableExprAsNonODRUsed(SansParensExpr);
   }
 }
 
@@ -15774,18 +15767,20 @@ void Sema::CleanupVarDeclMarking() {
   std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs);
 
   for (Expr *E : LocalMaybeODRUseExprs) {
-    if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
-      MarkVarDeclODRUsed(cast<VarDecl>(DRE->getDecl()),
-                         DRE->getLocation(), *this);
-    } else if (auto *ME = dyn_cast<MemberExpr>(E)) {
-      MarkVarDeclODRUsed(cast<VarDecl>(ME->getMemberDecl()), ME->getMemberLoc(),
-                         *this);
-    } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {
-      for (VarDecl *VD : *FP)
-        MarkVarDeclODRUsed(VD, FP->getParameterPackLocation(), *this);
+    VarDecl *Var;
+    SourceLocation Loc;
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+      Var = cast<VarDecl>(DRE->getDecl());
+      Loc = DRE->getLocation();
+    } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+      Var = cast<VarDecl>(ME->getMemberDecl());
+      Loc = ME->getMemberLoc();
     } else {
       llvm_unreachable("Unexpected expression");
     }
+
+    MarkVarDeclODRUsed(Var, Loc, *this,
+                       /*MaxFunctionScopeIndex Pointer*/ nullptr);
   }
 
   assert(MaybeODRUseExprs.empty() &&
@@ -15794,8 +15789,7 @@ void Sema::CleanupVarDeclMarking() {
 
 static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
                                     VarDecl *Var, Expr *E) {
-  assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E) ||
-          isa<FunctionParmPackExpr>(E)) &&
+  assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) &&
          "Invalid Expr argument to DoMarkVarDeclReferenced");
   Var->setReferenced();
 
@@ -16028,12 +16022,6 @@ void Sema::MarkMemberReferenced(MemberEx
   MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse);
 }
 
-/// Perform reference-marking and odr-use handling for a FunctionParmPackExpr.
-void Sema::MarkFunctionParmPackReferenced(FunctionParmPackExpr *E) {
-  for (VarDecl *VD : *E)
-    MarkExprReferenced(*this, E->getParameterPackLocation(), VD, E, true);
-}
-
 /// Perform marking for a reference to an arbitrary declaration.  It
 /// marks the declaration referenced, and performs odr-use checking for
 /// functions and variables. This method should not be used when building a

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jun  3 02:56:09 2019
@@ -7427,7 +7427,12 @@ static void CheckIfAnyEnclosingLambdasMu
   // All the potentially captureable variables in the current nested
   // lambda (within a generic outer lambda), must be captured by an
   // outer lambda that is enclosed within a non-dependent context.
-  CurrentLSI->visitPotentialCaptures([&] (VarDecl *Var, Expr *VarExpr) {
+  const unsigned NumPotentialCaptures =
+      CurrentLSI->getNumPotentialVariableCaptures();
+  for (unsigned I = 0; I != NumPotentialCaptures; ++I) {
+    Expr *VarExpr = nullptr;
+    VarDecl *Var = nullptr;
+    CurrentLSI->getPotentialVariableCapture(I, Var, VarExpr);
     // If the variable is clearly identified as non-odr-used and the full
     // expression is not instantiation dependent, only then do we not
     // need to check enclosing lambda's for speculative captures.
@@ -7441,7 +7446,7 @@ static void CheckIfAnyEnclosingLambdasMu
     // }
     if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) &&
         !IsFullExprInstantiationDependent)
-      return;
+      continue;
 
     // If we have a capture-capable lambda for the variable, go ahead and
     // capture the variable in that lambda (and all its enclosing lambdas).
@@ -7473,7 +7478,7 @@ static void CheckIfAnyEnclosingLambdasMu
                           DeclRefType, nullptr);
       }
     }
-  });
+  }
 
   // Check if 'this' needs to be captured.
   if (CurrentLSI->hasPotentialThisCapture()) {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Jun  3 02:56:09 2019
@@ -1368,11 +1368,9 @@ TemplateInstantiator::TransformFunctionP
     Vars.push_back(D);
   }
 
-  auto *PackExpr =
-      FunctionParmPackExpr::Create(getSema().Context, T, E->getParameterPack(),
-                                   E->getParameterPackLocation(), Vars);
-  getSema().MarkFunctionParmPackReferenced(PackExpr);
-  return PackExpr;
+  return FunctionParmPackExpr::Create(getSema().Context, T,
+                                      E->getParameterPack(),
+                                      E->getParameterPackLocation(), Vars);
 }
 
 ExprResult
@@ -1391,10 +1389,8 @@ TemplateInstantiator::TransformFunctionP
       QualType T = TransformType(E->getType());
       if (T.isNull())
         return ExprError();
-      auto *PackExpr = FunctionParmPackExpr::Create(getSema().Context, T, PD,
-                                                    E->getExprLoc(), *Pack);
-      getSema().MarkFunctionParmPackReferenced(PackExpr);
-      return PackExpr;
+      return FunctionParmPackExpr::Create(getSema().Context, T, PD,
+                                          E->getExprLoc(), *Pack);
     }
 
     TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jun  3 02:56:09 2019
@@ -660,10 +660,7 @@ public:
                                           bool ExpectParameterPack);
 
   /// Transform the body of a lambda-expression.
-  StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
-  /// Alternative implementation of TransformLambdaBody that skips transforming
-  /// the body.
-  StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
+  StmtResult TransformLambdaBody(Stmt *Body);
 
   QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
 
@@ -11361,13 +11358,16 @@ TreeTransform<Derived>::TransformLambdaE
   bool Invalid = false;
 
   // Transform captures.
+  bool FinishedExplicitCaptures = false;
   for (LambdaExpr::capture_iterator C = E->capture_begin(),
                                  CEnd = E->capture_end();
        C != CEnd; ++C) {
     // When we hit the first implicit capture, tell Sema that we've finished
     // the list of explicit captures.
-    if (C->isImplicit())
-      break;
+    if (!FinishedExplicitCaptures && C->isImplicit()) {
+      getSema().finishLambdaExplicitCaptures(LSI);
+      FinishedExplicitCaptures = true;
+    }
 
     // Capturing 'this' is trivial.
     if (C->capturesThis()) {
@@ -11476,16 +11476,17 @@ TreeTransform<Derived>::TransformLambdaE
     getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
                                  EllipsisLoc);
   }
-  getSema().finishLambdaExplicitCaptures(LSI);
+  if (!FinishedExplicitCaptures)
+    getSema().finishLambdaExplicitCaptures(LSI);
 
-  // FIXME: Sema's lambda-building mechanism expects us to push an expression
-  // evaluation context even if we're not transforming the function body.
+  // Enter a new evaluation context to insulate the lambda from any
+  // cleanups from the enclosing full-expression.
   getSema().PushExpressionEvaluationContext(
       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
 
   // Instantiate the body of the lambda expression.
   StmtResult Body =
-      Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
+      Invalid ? StmtError() : getDerived().TransformLambdaBody(E->getBody());
 
   // ActOnLambda* will pop the function scope for us.
   FuncScopeCleanup.disable();
@@ -11511,51 +11512,11 @@ TreeTransform<Derived>::TransformLambdaE
 
 template<typename Derived>
 StmtResult
-TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
+TreeTransform<Derived>::TransformLambdaBody(Stmt *S) {
   return TransformStmt(S);
 }
 
 template<typename Derived>
-StmtResult
-TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
-  // Transform captures.
-  for (LambdaExpr::capture_iterator C = E->capture_begin(),
-                                 CEnd = E->capture_end();
-       C != CEnd; ++C) {
-    // When we hit the first implicit capture, tell Sema that we've finished
-    // the list of explicit captures.
-    if (!C->isImplicit())
-      continue;
-
-    // Capturing 'this' is trivial.
-    if (C->capturesThis()) {
-      getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
-                                    /*BuildAndDiagnose*/ true, nullptr,
-                                    C->getCaptureKind() == LCK_StarThis);
-      continue;
-    }
-    // Captured expression will be recaptured during captured variables
-    // rebuilding.
-    if (C->capturesVLAType())
-      continue;
-
-    assert(C->capturesVariable() && "unexpected kind of lambda capture");
-    assert(!E->isInitCapture(C) && "implicit init-capture?");
-
-    // Transform the captured variable.
-    VarDecl *CapturedVar = cast_or_null<VarDecl>(
-        getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
-    if (!CapturedVar || CapturedVar->isInvalidDecl())
-      return StmtError();
-
-    // Capture the transformed variable.
-    getSema().tryCaptureVariable(CapturedVar, C->getLocation());
-  }
-
-  return S;
-}
-
-template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
                                                   CXXUnresolvedConstructExpr *E) {

Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp?rev=362375&r1=362374&r2=362375&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp Mon Jun  3 02:56:09 2019
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s
-// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only %s
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
@@ -177,13 +176,7 @@ void doit() {
     sample::X cx{5};
     auto L = [=](auto a) { 
       const int z = 3;
-      // FIXME: The warning below is correct but for some reason doesn't show
-      // up in C++17 mode.
       return [&,a](auto b) {
-#if __cplusplus > 201702L
-        // expected-warning at -2 {{address of stack memory associated with local variable 'z' returned}}
-        // expected-note@#call {{in instantiation of}}
-#endif
         const int y = 5;    
         return [=](auto c) { 
           int d[sizeof(a) == sizeof(c) || sizeof(c) == sizeof(b) ? 2 : 1];
@@ -196,7 +189,7 @@ void doit() {
         }; 
       };
     };
-    auto M = L(3)(3.5); // #call
+    auto M = L(3)(3.5);
     M(3.14);
   }
 }
@@ -1526,20 +1519,6 @@ void test() {
 
 } // end ns5
 
-} // end PR34266
 
-namespace capture_pack {
-#if __cplusplus >= 201702L
-  constexpr
-#endif
-  auto v =
-    [](auto ...a) {
-      [&](auto ...b) {
-        ((a = b), ...); // expected-warning 0-1{{extension}}
-      }(100, 20, 3);
-      return (a + ...); // expected-warning 0-1{{extension}}
-    }(400, 50, 6);
-#if __cplusplus >= 201702L
-  static_assert(v == 123);
-#endif
-}
+
+} // end PR34266

Removed: cfe/trunk/test/SemaTemplate/lambda-capture-pack.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/lambda-capture-pack.cpp?rev=362374&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/lambda-capture-pack.cpp (original)
+++ cfe/trunk/test/SemaTemplate/lambda-capture-pack.cpp (removed)
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -verify %s
-// expected-no-diagnostics
-
-template<typename ...T, typename ...Lambda> void check_sizes(Lambda ...L) {
-  static_assert(((sizeof(T) == sizeof(Lambda)) && ...));
-}
-
-template<typename ...T> void f(T ...v) {
-  // Pack expansion of lambdas: each lambda captures only one pack element.
-  check_sizes<T...>([=] { (void)&v; } ...);
-
-  // Pack expansion inside lambda: captures all pack elements.
-  auto l = [=] { ((void)&v, ...); };
-  static_assert(sizeof(l) >= (sizeof(T) + ...));
-}
-
-template void f(int, char, double);




More information about the cfe-commits mailing list