[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