]> granicus.if.org Git - clang/commitdiff
This patch extends CleanupScope to support destruction
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 4 Nov 2009 17:57:40 +0000 (17:57 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 4 Nov 2009 17:57:40 +0000 (17:57 +0000)
of array objects on block exit. Patch is by Anders Calrsson.

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

lib/CodeGen/CGDecl.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/array-construction.cpp

index b1ceb4627712738bf9a65dbf27f2c6fbbafb7b05..2021ced31683cfb00ff10450138c55d5ee970297 100644 (file)
@@ -515,18 +515,22 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
         const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext());
         assert(D && "EmitLocalBlockVarDecl - destructor is nul");
         
-        CleanupScope scope(*this);
         if (const ConstantArrayType *Array = 
               getContext().getAsConstantArrayType(Ty)) {
+          CleanupScope Scope(*this);
           QualType BaseElementTy = getContext().getBaseElementType(Array);
           const llvm::Type *BasePtr = ConvertType(BaseElementTy);
           BasePtr = llvm::PointerType::getUnqual(BasePtr);
           llvm::Value *BaseAddrPtr =
             Builder.CreateBitCast(DeclPtr, BasePtr);
           EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
-        }
-        else
+          
+          // Make sure to jump to the exit block.
+          EmitBranch(Scope.getCleanupExitBlock());
+        } else {
+          CleanupScope Scope(*this);
           EmitCXXDestructorCall(D, Dtor_Complete, DeclPtr);
+        }
       }
   }
 
index 88beadf331407a902ec5d7b9b84b7328f1cc30d9..4be341311ce4735cefd4025d7ea2e90e7ac885b9 100644 (file)
@@ -665,8 +665,9 @@ llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
   return EmitLValue(E).getAddress();
 }
 
-void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupBlock) {
-  CleanupEntries.push_back(CleanupEntry(CleanupBlock));
+void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
+                                       llvm::BasicBlock *CleanupExitBlock) {
+  CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock));
 }
 
 void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
@@ -680,7 +681,7 @@ void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
 CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
   CleanupEntry &CE = CleanupEntries.back();
 
-  llvm::BasicBlock *CleanupBlock = CE.CleanupBlock;
+  llvm::BasicBlock *CleanupEntryBlock = CE.CleanupEntryBlock;
 
   std::vector<llvm::BasicBlock *> Blocks;
   std::swap(Blocks, CE.Blocks);
@@ -711,10 +712,11 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
     }
   }
 
-  llvm::BasicBlock *SwitchBlock = 0;
+  llvm::BasicBlock *SwitchBlock = CE.CleanupExitBlock;
   llvm::BasicBlock *EndBlock = 0;
   if (!BranchFixups.empty()) {
-    SwitchBlock = createBasicBlock("cleanup.switch");
+    if (!SwitchBlock)
+      SwitchBlock = createBasicBlock("cleanup.switch");
     EndBlock = createBasicBlock("cleanup.end");
 
     llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
@@ -745,7 +747,7 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
       llvm::BasicBlock *Dest = BI->getSuccessor(0);
 
       // Fixup the branch instruction to point to the cleanup block.
-      BI->setSuccessor(0, CleanupBlock);
+      BI->setSuccessor(0, CleanupEntryBlock);
 
       if (CleanupEntries.empty()) {
         llvm::ConstantInt *ID;
@@ -802,7 +804,7 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
     BlockScopes.erase(Blocks[i]);
   }
 
-  return CleanupBlockInfo(CleanupBlock, SwitchBlock, EndBlock);
+  return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock);
 }
 
 void CodeGenFunction::EmitCleanupBlock() {
index 9bb219642ab43a90628a6dca26de0c4777b94a2d..fe8113e95332489588201efffebd239f1111990a 100644 (file)
@@ -108,11 +108,12 @@ public:
 
   /// PushCleanupBlock - Push a new cleanup entry on the stack and set the
   /// passed in block as the cleanup block.
-  void PushCleanupBlock(llvm::BasicBlock *CleanupBlock);
+  void PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
+                        llvm::BasicBlock *CleanupExitBlock = 0);
 
   /// CleanupBlockInfo - A struct representing a popped cleanup block.
   struct CleanupBlockInfo {
-    /// CleanupBlock - the cleanup block
+    /// CleanupEntryBlock - the cleanup entry block
     llvm::BasicBlock *CleanupBlock;
 
     /// SwitchBlock - the block (if any) containing the switch instruction used
@@ -138,17 +139,24 @@ public:
   class CleanupScope {
     CodeGenFunction& CGF;
     llvm::BasicBlock *CurBB;
-    llvm::BasicBlock *CleanupBB;
-
+    llvm::BasicBlock *CleanupEntryBB;
+    llvm::BasicBlock *CleanupExitBB;
+    
   public:
     CleanupScope(CodeGenFunction &cgf)
-      : CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()) {
-      CleanupBB = CGF.createBasicBlock("cleanup");
-      CGF.Builder.SetInsertPoint(CleanupBB);
+      : CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()),
+      CleanupEntryBB(CGF.createBasicBlock("cleanup")), CleanupExitBB(0) {
+      CGF.Builder.SetInsertPoint(CleanupEntryBB);
     }
 
+    llvm::BasicBlock *getCleanupExitBlock() {
+      if (!CleanupExitBB)
+        CleanupExitBB = CGF.createBasicBlock("cleanup.exit");
+      return CleanupExitBB;
+    }
+    
     ~CleanupScope() {
-      CGF.PushCleanupBlock(CleanupBB);
+      CGF.PushCleanupBlock(CleanupEntryBB, CleanupExitBB);
       // FIXME: This is silly, move this into the builder.
       if (CurBB)
         CGF.Builder.SetInsertPoint(CurBB);
@@ -250,9 +258,12 @@ private:
   bool DidCallStackSave;
 
   struct CleanupEntry {
-    /// CleanupBlock - The block of code that does the actual cleanup.
-    llvm::BasicBlock *CleanupBlock;
+    /// CleanupEntryBlock - The block of code that does the actual cleanup.
+    llvm::BasicBlock *CleanupEntryBlock;
 
+    /// CleanupExitBlock - The cleanup exit block.
+    llvm::BasicBlock *CleanupExitBlock;
+    
     /// Blocks - Basic blocks that were emitted in the current cleanup scope.
     std::vector<llvm::BasicBlock *> Blocks;
 
@@ -260,8 +271,10 @@ private:
     /// inserted into the current function yet.
     std::vector<llvm::BranchInst *> BranchFixups;
 
-    explicit CleanupEntry(llvm::BasicBlock *cb)
-      : CleanupBlock(cb) {}
+    explicit CleanupEntry(llvm::BasicBlock *CleanupEntryBlock,
+                          llvm::BasicBlock *CleanupExitBlock)
+      : CleanupEntryBlock(CleanupEntryBlock), 
+      CleanupExitBlock(CleanupExitBlock) {}
   };
 
   /// CleanupEntries - Stack of cleanup entries.
index b444221533d3168817d496bf5eb3d1f95c5ea1ff..5b6bc2e5b5114f5d94dd4af7a71d796f7c527e85 100644 (file)
@@ -17,12 +17,9 @@ public:
   int i;
   float f;
 
-/**
-  NYI
   ~xpto() {
     printf("xpto::~xpto()\n");
   }
-*/
 };
 
 int main() {