diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index bc422db8b91..a5b766ad73b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8615,6 +8615,10 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) { PushDeclContext(CurScope, Block); else CurContext = Block; + + // Enter a new evaluation context to insulate the block from any + // cleanups from the enclosing full-expression. + PushExpressionEvaluationContext(PotentiallyEvaluated); } void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { @@ -8742,6 +8746,10 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { /// ActOnBlockError - If there is an error parsing a block, this callback /// is invoked to pop the information about the block from the action impl. void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) { + // Leave the expression-evaluation context. + DiscardCleanupsInEvaluationContext(); + PopExpressionEvaluationContext(); + // Pop off CurBlock, handle nested blocks. PopDeclContext(); PopFunctionOrBlockScope(); @@ -8755,6 +8763,10 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (!LangOpts.Blocks) Diag(CaretLoc, diag::err_blocks_disable); + // Leave the expression-evaluation context. + assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!"); + PopExpressionEvaluationContext(); + BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); PopDeclContext(); |

