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 { }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits