[cfe-commits] r144362 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/CodeGenCXX/blocks.cpp
John McCall
rjmccall at apple.com
Thu Nov 10 19:19:13 PST 2011
Author: rjmccall
Date: Thu Nov 10 21:19:12 2011
New Revision: 144362
URL: http://llvm.org/viewvc/llvm-project?rev=144362&view=rev
Log:
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.
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/CodeGenCXX/blocks.cpp
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=144362&r1=144361&r2=144362&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Nov 10 21:19:12 2011
@@ -8615,6 +8615,10 @@
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 @@
/// 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 @@
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();
Modified: cfe/trunk/test/CodeGenCXX/blocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/blocks.cpp?rev=144362&r1=144361&r2=144362&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/blocks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/blocks.cpp Thu Nov 10 21:19:12 2011
@@ -178,3 +178,28 @@
// CHECK: call void @_ZN5test51AD1Ev([[A]]* [[X]])
// CHECK-NEXT: ret void
}
+
+namespace test6 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ void foo(const A &, void (^)());
+ void bar();
+
+ void test() {
+ // Make sure that the temporary cleanup isn't somehow captured
+ // within the block.
+ foo(A(), ^{ bar(); });
+ bar();
+ }
+
+ // CHECK: define void @_ZN5test64testEv()
+ // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[TEMP]])
+ // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
+ // CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* [[TEMP]])
+ // CHECK-NEXT: call void @_ZN5test63barEv()
+ // CHECK-NEXT: ret void
+}
More information about the cfe-commits
mailing list