[cfe-commits] r86032 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/array-construction.cpp

Fariborz Jahanian fjahanian at apple.com
Wed Nov 4 09:57:43 PST 2009


Author: fjahanian
Date: Wed Nov  4 11:57:40 2009
New Revision: 86032

URL: http://llvm.org/viewvc/llvm-project?rev=86032&view=rev
Log:
This patch extends CleanupScope to support destruction
of array objects on block exit. Patch is by Anders Calrsson.


Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenCXX/array-construction.cpp

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=86032&r1=86031&r2=86032&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Nov  4 11:57:40 2009
@@ -515,18 +515,22 @@
         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);
+        }
       }
   }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=86032&r1=86031&r2=86032&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Nov  4 11:57:40 2009
@@ -665,8 +665,9 @@
   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 @@
 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 @@
     }
   }
 
-  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 @@
       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 @@
     BlockScopes.erase(Blocks[i]);
   }
 
-  return CleanupBlockInfo(CleanupBlock, SwitchBlock, EndBlock);
+  return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock);
 }
 
 void CodeGenFunction::EmitCleanupBlock() {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=86032&r1=86031&r2=86032&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov  4 11:57:40 2009
@@ -108,11 +108,12 @@
 
   /// 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 @@
   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 @@
   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 @@
     /// 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.

Modified: cfe/trunk/test/CodeGenCXX/array-construction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/array-construction.cpp?rev=86032&r1=86031&r2=86032&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/array-construction.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/array-construction.cpp Wed Nov  4 11:57:40 2009
@@ -17,12 +17,9 @@
   int i;
   float f;
 
-/**
-  NYI
   ~xpto() {
     printf("xpto::~xpto()\n");
   }
-*/
 };
 
 int main() {





More information about the cfe-commits mailing list