[llvm-branch-commits] [cfe-branch] r286966 - Merging r286584:

Alexey Bataev via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Nov 15 06:23:10 PST 2016


Author: abataev
Date: Tue Nov 15 08:23:10 2016
New Revision: 286966

URL: http://llvm.org/viewvc/llvm-project?rev=286966&view=rev
Log:
Merging r286584:
------------------------------------------------------------------------
r286584 | abataev | 2016-11-11 12:36:20 +0000 (Fri, 11 Nov 2016) | 31 lines

Fix for PR28523: unexpected compilation error.

Clang emits error message for the following code:
```
template <class F> void parallel_loop(F &&f) { f(0); }

int main() {
  int x;
  parallel_loop([&](auto y) {
    {
      x = y;
    };
  });
}
```

$ clang++ --std=gnu++14 clang_test.cc -o clang_test
clang_test.cc:9:7: error: reference to local variable 'x' declared in enclosing function 'main'
      x = y;
            ^
clang_test.cc:2:48: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<int>' requested here
            template <class F> void parallel_loop(F &&f) { f(0); }
                                                           ^
clang_test.cc:6:3: note: in instantiation of function template specialization 'parallel_loop<(lambda at clang_test.cc:6:17)>' requested here parallel_loop([&](auto y) {
           ^
clang_test.cc:5:7: note: 'x' declared here
      int x;
          ^
1 error generated.

Patch fixes this issue.
------------------------------------------------------------------------

Added:
    cfe/branches/release_39/test/CodeGenCXX/PR28523.cpp
      - copied unchanged from r286584, cfe/trunk/test/CodeGenCXX/PR28523.cpp
Modified:
    cfe/branches/release_39/   (props changed)
    cfe/branches/release_39/include/clang/Sema/Sema.h
    cfe/branches/release_39/lib/Sema/Sema.cpp
    cfe/branches/release_39/lib/Sema/SemaExpr.cpp
    cfe/branches/release_39/lib/Sema/SemaExprCXX.cpp
    cfe/branches/release_39/lib/Sema/SemaLambda.cpp

Propchange: cfe/branches/release_39/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov 15 08:23:10 2016
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276900,276979,276983,277095,277138,277141,277221,277307,277522,277743,277783,277796-277797,277852,277866,277889,277900,278139,278156,278234-278235,278393,278395,278763,278786,278988,284110,286103,286106,286129
+/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276900,276979,276983,277095,277138,277141,277221,277307,277522,277743,277783,277796-277797,277852,277866,277889,277900,278139,278156,278234-278235,278393,278395,278763,278786,278988,284110,286103,286106,286129,286584
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_39/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/include/clang/Sema/Sema.h?rev=286966&r1=286965&r2=286966&view=diff
==============================================================================
--- cfe/branches/release_39/include/clang/Sema/Sema.h (original)
+++ cfe/branches/release_39/include/clang/Sema/Sema.h Tue Nov 15 08:23:10 2016
@@ -1218,8 +1218,10 @@ public:
   /// \brief Retrieve the current block, if any.
   sema::BlockScopeInfo *getCurBlock();
 
-  /// \brief Retrieve the current lambda scope info, if any.
-  sema::LambdaScopeInfo *getCurLambda();
+  /// Retrieve the current lambda scope info, if any.
+  /// \param IgnoreCapturedRegions true if should find the top-most lambda scope
+  /// info ignoring all inner captured regions scope infos.
+  sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false);
 
   /// \brief Retrieve the current generic lambda info, if any.
   sema::LambdaScopeInfo *getCurGenericLambda();

Modified: cfe/branches/release_39/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/Sema.cpp?rev=286966&r1=286965&r2=286966&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/Sema.cpp (original)
+++ cfe/branches/release_39/lib/Sema/Sema.cpp Tue Nov 15 08:23:10 2016
@@ -1197,11 +1197,19 @@ BlockScopeInfo *Sema::getCurBlock() {
   return CurBSI;
 }
 
-LambdaScopeInfo *Sema::getCurLambda() {
+LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
   if (FunctionScopes.empty())
     return nullptr;
 
-  auto CurLSI = dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
+  auto I = FunctionScopes.rbegin();
+  if (IgnoreCapturedRegions) {
+    auto E = FunctionScopes.rend();
+    while (I != E && isa<CapturedRegionScopeInfo>(*I))
+      ++I;
+    if (I == E)
+      return nullptr;
+  }
+  auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I);
   if (CurLSI && CurLSI->Lambda &&
       !CurLSI->Lambda->Encloses(CurContext)) {
     // We have switched contexts due to template instantiation.

Modified: cfe/branches/release_39/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/SemaExpr.cpp?rev=286966&r1=286965&r2=286966&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/release_39/lib/Sema/SemaExpr.cpp Tue Nov 15 08:23:10 2016
@@ -13885,7 +13885,8 @@ static void DoMarkVarDeclReferenced(Sema
         (SemaRef.CurContext != Var->getDeclContext() &&
          Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
     if (RefersToEnclosingScope) {
-      if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {
+      if (LambdaScopeInfo *const LSI =
+              SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
         // If a variable could potentially be odr-used, defer marking it so
         // until we finish analyzing the full expression for any
         // lvalue-to-rvalue

Modified: cfe/branches/release_39/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/SemaExprCXX.cpp?rev=286966&r1=286965&r2=286966&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/release_39/lib/Sema/SemaExprCXX.cpp Tue Nov 15 08:23:10 2016
@@ -6582,10 +6582,16 @@ static inline bool VariableCanNeverBeACo
 static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
     Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {
 
-  assert(!S.isUnevaluatedContext());  
-  assert(S.CurContext->isDependentContext()); 
-  assert(CurrentLSI->CallOperator == S.CurContext && 
+  assert(!S.isUnevaluatedContext());
+  assert(S.CurContext->isDependentContext());
+#ifndef NDEBUG
+  DeclContext *DC = S.CurContext;
+  while (DC && isa<CapturedDecl>(DC))
+    DC = DC->getParent();
+  assert(
+      CurrentLSI->CallOperator == DC &&
       "The current call operator must be synchronized with Sema's CurContext");
+#endif // NDEBUG
 
   const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
 
@@ -7051,7 +7057,8 @@ ExprResult Sema::ActOnFinishFullExpr(Exp
   // and then the full-expression +n + ({ 0; }); ends, but it's too late 
   // for us to see that we need to capture n after all.
 
-  LambdaScopeInfo *const CurrentLSI = getCurLambda();
+  LambdaScopeInfo *const CurrentLSI =
+      getCurLambda(/*IgnoreCapturedRegions=*/true);
   // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer 
   // even if CurContext is not a lambda call operator. Refer to that Bug Report
   // for an example of the code that might cause this asynchrony.  
@@ -7066,7 +7073,10 @@ ExprResult Sema::ActOnFinishFullExpr(Exp
   //     constructor/destructor.
   //  - Teach the handful of places that iterate over FunctionScopes to 
   //    stop at the outermost enclosing lexical scope."
-  const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext);
+  DeclContext *DC = CurContext;
+  while (DC && isa<CapturedDecl>(DC))
+    DC = DC->getParent();
+  const bool IsInLambdaDeclContext = isLambdaCallOperator(DC);
   if (IsInLambdaDeclContext && CurrentLSI &&
       CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid())
     CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI,

Modified: cfe/branches/release_39/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/SemaLambda.cpp?rev=286966&r1=286965&r2=286966&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/SemaLambda.cpp (original)
+++ cfe/branches/release_39/lib/Sema/SemaLambda.cpp Tue Nov 15 08:23:10 2016
@@ -66,17 +66,20 @@ getStackIndexOfNearestEnclosingCaptureRe
   // Label failure to capture.
   const Optional<unsigned> NoLambdaIsCaptureReady;
 
+  // Ignore all inner captured regions.
+  unsigned CurScopeIndex = FunctionScopes.size() - 1;
+  while (CurScopeIndex > 0 && isa<clang::sema::CapturedRegionScopeInfo>(
+                                  FunctionScopes[CurScopeIndex]))
+    --CurScopeIndex;
   assert(
-      isa<clang::sema::LambdaScopeInfo>(
-          FunctionScopes[FunctionScopes.size() - 1]) &&
+      isa<clang::sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]) &&
       "The function on the top of sema's function-info stack must be a lambda");
-  
+
   // If VarToCapture is null, we are attempting to capture 'this'.
   const bool IsCapturingThis = !VarToCapture;
   const bool IsCapturingVariable = !IsCapturingThis;
 
   // Start with the current lambda at the top of the stack (highest index).
-  unsigned CurScopeIndex = FunctionScopes.size() - 1;
   DeclContext *EnclosingDC =
       cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator;
 




More information about the llvm-branch-commits mailing list