forked from OSchip/llvm-project
[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 llvm-svn: 296584
This commit is contained in:
parent
1a1d959423
commit
7cbbb88f23
|
@ -1244,9 +1244,11 @@ public:
|
||||||
sema::BlockScopeInfo *getCurBlock();
|
sema::BlockScopeInfo *getCurBlock();
|
||||||
|
|
||||||
/// Retrieve the current lambda scope info, if any.
|
/// Retrieve the current lambda scope info, if any.
|
||||||
/// \param IgnoreCapturedRegions true if should find the top-most lambda scope
|
/// \param IgnoreNonLambdaCapturingScope true if should find the top-most
|
||||||
/// info ignoring all inner captured regions scope infos.
|
/// lambda scope info ignoring all inner capturing scopes that are not
|
||||||
sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false);
|
/// lambda scopes.
|
||||||
|
sema::LambdaScopeInfo *
|
||||||
|
getCurLambda(bool IgnoreNonLambdaCapturingScope = false);
|
||||||
|
|
||||||
/// \brief Retrieve the current generic lambda info, if any.
|
/// \brief Retrieve the current generic lambda info, if any.
|
||||||
sema::LambdaScopeInfo *getCurGenericLambda();
|
sema::LambdaScopeInfo *getCurGenericLambda();
|
||||||
|
|
|
@ -1237,14 +1237,14 @@ BlockScopeInfo *Sema::getCurBlock() {
|
||||||
return CurBSI;
|
return CurBSI;
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
|
LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
|
||||||
if (FunctionScopes.empty())
|
if (FunctionScopes.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto I = FunctionScopes.rbegin();
|
auto I = FunctionScopes.rbegin();
|
||||||
if (IgnoreCapturedRegions) {
|
if (IgnoreNonLambdaCapturingScope) {
|
||||||
auto E = FunctionScopes.rend();
|
auto E = FunctionScopes.rend();
|
||||||
while (I != E && isa<CapturedRegionScopeInfo>(*I))
|
while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I))
|
||||||
++I;
|
++I;
|
||||||
if (I == E)
|
if (I == E)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -14303,8 +14303,9 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
|
||||||
(SemaRef.CurContext != Var->getDeclContext() &&
|
(SemaRef.CurContext != Var->getDeclContext() &&
|
||||||
Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
|
Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
|
||||||
if (RefersToEnclosingScope) {
|
if (RefersToEnclosingScope) {
|
||||||
if (LambdaScopeInfo *const LSI =
|
LambdaScopeInfo *const LSI =
|
||||||
SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
|
SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true);
|
||||||
|
if (LSI && !LSI->CallOperator->Encloses(Var->getDeclContext())) {
|
||||||
// If a variable could potentially be odr-used, defer marking it so
|
// If a variable could potentially be odr-used, defer marking it so
|
||||||
// until we finish analyzing the full expression for any
|
// until we finish analyzing the full expression for any
|
||||||
// lvalue-to-rvalue
|
// lvalue-to-rvalue
|
||||||
|
|
|
@ -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;
|
@protocol NSObject;
|
||||||
|
|
||||||
void bar(id(^)(void));
|
void bar(id(^)(void));
|
||||||
|
@ -145,6 +145,17 @@ namespace DependentReturn {
|
||||||
template void f<X>(X);
|
template void f<X>(X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace GenericLambdaCapture {
|
||||||
|
int test(int outerp) {
|
||||||
|
auto lambda =[&](auto p) {
|
||||||
|
return ^{
|
||||||
|
return p + outerp;
|
||||||
|
}();
|
||||||
|
};
|
||||||
|
return lambda(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace MoveBlockVariable {
|
namespace MoveBlockVariable {
|
||||||
struct B0 {
|
struct B0 {
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue