From c33e4ba20304e222692e77f2c6ad26a5d8d32f83 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 6 Oct 2009 18:09:57 +0000 Subject: [PATCH] Emit the destructor epilogue in a cleanup block so a return from a destructor body still calls the epilogue. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83397 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.cpp | 21 ++++++++++++++++++++- test/CodeGenCXX/destructor-calls.cpp | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index f9e54b7570..f802068b26 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -233,11 +233,30 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, // FIXME: Support CXXTryStmt here, too. if (const CompoundStmt *S = FD->getCompoundBody()) { StartFunction(GD, FD->getResultType(), Fn, Args, S->getLBracLoc()); + const CXXDestructorDecl *DD = dyn_cast(FD); + llvm::BasicBlock *DtorEpilogue = 0; + if (DD) { + DtorEpilogue = createBasicBlock("dtor.epilogue"); + + PushCleanupBlock(DtorEpilogue); + } + if (const CXXConstructorDecl *CD = dyn_cast(FD)) EmitCtorPrologue(CD, GD.getCtorType()); EmitStmt(S); - if (const CXXDestructorDecl *DD = dyn_cast(FD)) + + if (DD) { + CleanupBlockInfo Info = PopCleanupBlock(); + + assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!"); + EmitBlock(DtorEpilogue); EmitDtorEpilogue(DD, GD.getDtorType()); + + if (Info.SwitchBlock) + EmitBlock(Info.SwitchBlock); + if (Info.EndBlock) + EmitBlock(Info.EndBlock); + } FinishFunction(S->getRBracLoc()); } else if (FD->isImplicit()) { const CXXRecordDecl *ClassDecl = diff --git a/test/CodeGenCXX/destructor-calls.cpp b/test/CodeGenCXX/destructor-calls.cpp index 7b9225590a..3f0288b85c 100644 --- a/test/CodeGenCXX/destructor-calls.cpp +++ b/test/CodeGenCXX/destructor-calls.cpp @@ -30,7 +30,12 @@ struct N : M, P { P p; }; +struct O : B { + ~O() { return; } +}; + int main() { N n1; N n2; + O o; } -- 2.40.0