r296584 - [Sema] Add variable captured by a block to the enclosing lambda's

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 28 22:11:25 PST 2017


Author: ahatanak
Date: Wed Mar  1 00:11:25 2017
New Revision: 296584

URL: http://llvm.org/viewvc/llvm-project?rev=296584&view=rev
Log:
[Sema] Add variable captured by a block to the enclosing lambda's
potential capture list.

Fix Sema::getCurLambda() to return the innermost lambda scope when there
is a block enclosed in the lambda. Previously, the method would return a
nullptr in such cases, which would prevent a variable captured by the
enclosed block to be added to the lambda scope's potential capture list.

rdar://problem/28412462

Differential Revision: https://reviews.llvm.org/D25556

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaObjCXX/blocks.mm

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=296584&r1=296583&r2=296584&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar  1 00:11:25 2017
@@ -1244,9 +1244,11 @@ public:
   sema::BlockScopeInfo *getCurBlock();
 
   /// 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);
+  /// \param IgnoreNonLambdaCapturingScope true if should find the top-most
+  /// lambda scope info ignoring all inner capturing scopes that are not
+  /// lambda scopes.
+  sema::LambdaScopeInfo *
+  getCurLambda(bool IgnoreNonLambdaCapturingScope = false);
 
   /// \brief Retrieve the current generic lambda info, if any.
   sema::LambdaScopeInfo *getCurGenericLambda();

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=296584&r1=296583&r2=296584&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Mar  1 00:11:25 2017
@@ -1237,14 +1237,14 @@ BlockScopeInfo *Sema::getCurBlock() {
   return CurBSI;
 }
 
-LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
+LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
   if (FunctionScopes.empty())
     return nullptr;
 
   auto I = FunctionScopes.rbegin();
-  if (IgnoreCapturedRegions) {
+  if (IgnoreNonLambdaCapturingScope) {
     auto E = FunctionScopes.rend();
-    while (I != E && isa<CapturedRegionScopeInfo>(*I))
+    while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I))
       ++I;
     if (I == E)
       return nullptr;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=296584&r1=296583&r2=296584&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Mar  1 00:11:25 2017
@@ -14303,8 +14303,9 @@ static void DoMarkVarDeclReferenced(Sema
         (SemaRef.CurContext != Var->getDeclContext() &&
          Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
     if (RefersToEnclosingScope) {
-      if (LambdaScopeInfo *const LSI =
-              SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
+      LambdaScopeInfo *const LSI =
+          SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true);
+      if (LSI && !LSI->CallOperator->Encloses(Var->getDeclContext())) {
         // 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/trunk/test/SemaObjCXX/blocks.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/blocks.mm?rev=296584&r1=296583&r2=296584&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/blocks.mm (original)
+++ cfe/trunk/test/SemaObjCXX/blocks.mm Wed Mar  1 00:11:25 2017
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s
 @protocol NSObject;
 
 void bar(id(^)(void));
@@ -145,6 +145,17 @@ namespace DependentReturn {
   template void f<X>(X);
 }
 
+namespace GenericLambdaCapture {
+int test(int outerp) {
+  auto lambda =[&](auto p) {
+    return ^{
+      return p + outerp;
+    }();
+  };
+  return lambda(1);
+}
+}
+
 namespace MoveBlockVariable {
 struct B0 {
 };




More information about the cfe-commits mailing list