diff options
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 84220f7c9c7..e27bfd80505 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5988,9 +5988,24 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, // 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(); - if (CurrentLSI && CurrentLSI->hasPotentialCaptures() && - !FullExpr.isInvalid()) + LambdaScopeInfo *const CurrentLSI = getCurLambda(); + // 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. + // By ensuring we are in the context of a lambda's call operator + // we can fix the bug (we only need to check whether we need to capture + // if we are within a lambda's body); but per the comments in that + // PR, a proper fix would entail : + // "Alternative suggestion: + // - Add to Sema an integer holding the smallest (outermost) scope + // index that we are *lexically* within, and save/restore/set to + // FunctionScopes.size() in InstantiatingTemplate's + // constructor/destructor. + // - Teach the handful of places that iterate over FunctionScopes to + // stop at the outermost enclosing lexical scope." + const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext); + if (IsInLambdaDeclContext && CurrentLSI && + CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid()) CheckLambdaCaptures(FE, CurrentLSI, *this); return MaybeCreateExprWithCleanups(FullExpr); } |