]> granicus.if.org Git - clang/commitdiff
Be sure to insulate block literals from any cleanups in their
authorJohn McCall <rjmccall@apple.com>
Fri, 11 Nov 2011 03:19:12 +0000 (03:19 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 11 Nov 2011 03:19:12 +0000 (03:19 +0000)
enclosing full-expressions.  It is somewhat amazing that
this hasn't come up as a problem before.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144362 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CodeGenCXX/blocks.cpp

index bc422db8b912139258abfb1bacbef97b556429b1..a5b766ad73b3fa4a7f94d9e7d172e2a7b9bc04ed 100644 (file)
@@ -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();
index 40faf1bf235d931b9d2a5d62393c9ed52df8c4fc..921d94a138a0cb97747a5a32d93f19341db86a31 100644 (file)
@@ -178,3 +178,28 @@ namespace test5 {
   // 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
+}