From: Fariborz Jahanian Date: Wed, 4 Nov 2009 17:57:40 +0000 (+0000) Subject: This patch extends CleanupScope to support destruction X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7799621ad7d16f3c6a1aeda024312d63ecd77777;p=clang This patch extends CleanupScope to support destruction 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 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index b1ceb46277..2021ced316 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -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); + } } } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 88beadf331..4be341311c 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -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 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() { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 9bb219642a..fe8113e953 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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 Blocks; @@ -260,8 +271,10 @@ private: /// inserted into the current function yet. std::vector 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. diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp index b444221533..5b6bc2e5b5 100644 --- a/test/CodeGenCXX/array-construction.cpp +++ b/test/CodeGenCXX/array-construction.cpp @@ -17,12 +17,9 @@ public: int i; float f; -/** - NYI ~xpto() { printf("xpto::~xpto()\n"); } -*/ }; int main() {