diff options
| author | John McCall <rjmccall@apple.com> | 2011-11-11 03:19:12 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-11-11 03:19:12 +0000 |
| commit | f1a3c2aee1de6af989d52acf631b50713597e69d (patch) | |
| tree | 98adb3b1261d0fbb87260787c5b4789d04e2aa6f /clang/lib | |
| parent | c4a001478c813b8f6f14d781f325da2ef4f689fd (diff) | |
| download | bcm5719-llvm-f1a3c2aee1de6af989d52acf631b50713597e69d.tar.gz bcm5719-llvm-f1a3c2aee1de6af989d52acf631b50713597e69d.zip | |
Be sure to insulate block literals from any cleanups in their
enclosing full-expressions. It is somewhat amazing that
this hasn't come up as a problem before.
llvm-svn: 144362
Diffstat (limited to 'clang/lib')
| -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(); |

