Emit the destructor epilogue in a cleanup block so a return from a destructor body still calls the epilogue.

llvm-svn: 83397
This commit is contained in:
Anders Carlsson 2009-10-06 18:09:57 +00:00
parent 36d1b14dde
commit 6b7378bbe1
2 changed files with 25 additions and 1 deletions

View File

@ -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<CXXDestructorDecl>(FD);
llvm::BasicBlock *DtorEpilogue = 0;
if (DD) {
DtorEpilogue = createBasicBlock("dtor.epilogue");
PushCleanupBlock(DtorEpilogue);
}
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
EmitCtorPrologue(CD, GD.getCtorType());
EmitStmt(S);
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(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 =

View File

@ -30,7 +30,12 @@ struct N : M, P {
P p;
};
struct O : B {
~O() { return; }
};
int main() {
N n1;
N n2;
O o;
}