ahatanak updated this revision to Diff 82394. ahatanak added a comment. Rebase.
r286584 changed getCurLambda to optionally skip CapturedRegionScopeInfos. This patch changes it to skip BlockScopeInfos too. https://reviews.llvm.org/D25556 Files: include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaExpr.cpp test/SemaObjCXX/blocks.mm Index: test/SemaObjCXX/blocks.mm =================================================================== --- test/SemaObjCXX/blocks.mm +++ test/SemaObjCXX/blocks.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s @protocol NSObject; void bar(id(^)(void)); @@ -144,3 +144,14 @@ template void f<X>(X); } + +namespace GenericLambdaCapture { + int test(int outerp) { + auto lambda =[&](auto p) { + return ^{ + return p + outerp; + }(); + }; + return lambda(1); + } +} Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14126,8 +14126,9 @@ (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 Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -1243,14 +1243,14 @@ 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; Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1226,9 +1226,11 @@ 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();
Index: test/SemaObjCXX/blocks.mm =================================================================== --- test/SemaObjCXX/blocks.mm +++ test/SemaObjCXX/blocks.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s @protocol NSObject; void bar(id(^)(void)); @@ -144,3 +144,14 @@ template void f<X>(X); } + +namespace GenericLambdaCapture { + int test(int outerp) { + auto lambda =[&](auto p) { + return ^{ + return p + outerp; + }(); + }; + return lambda(1); + } +} Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14126,8 +14126,9 @@ (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 Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -1243,14 +1243,14 @@ 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; Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1226,9 +1226,11 @@ 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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits