summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-11-11 12:36:20 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-11-11 12:36:20 +0000
commit31939e39db2ca3f26868f1f961be0e6c9026a45c (patch)
treea0bd1889030cc7429def9f841ae3aca8002d998b /clang/lib/Sema/SemaExprCXX.cpp
parentcdfdff0b182a8a4a06ba99d7410f0d129b743a45 (diff)
downloadbcm5719-llvm-31939e39db2ca3f26868f1f961be0e6c9026a45c.tar.gz
bcm5719-llvm-31939e39db2ca3f26868f1f961be0e6c9026a45c.zip
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. llvm-svn: 286584
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 0dab27affea..634954c3e85 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6879,8 +6879,14 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
assert(!S.isUnevaluatedContext());
assert(S.CurContext->isDependentContext());
- assert(CurrentLSI->CallOperator == S.CurContext &&
+#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();
@@ -7346,7 +7352,8 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
// 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.
@@ -7361,7 +7368,10 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
// 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,
OpenPOWER on IntegriCloud