]> granicus.if.org Git - clang/commitdiff
Emit the destructor epilogue in a cleanup block so a return from a destructor body...
authorAnders Carlsson <andersca@mac.com>
Tue, 6 Oct 2009 18:09:57 +0000 (18:09 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 6 Oct 2009 18:09:57 +0000 (18:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83397 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/destructor-calls.cpp

index f9e54b75708f6fda4d92ae502f7bd6a5d50bd5ea..f802068b26d3444066b9aef14e96fa066d76c44b 100644 (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 =
index 7b9225590a7b7023264885443e9e72a4e9f96cad..3f0288b85c14f1665162a160723ba407597a1fc4 100644 (file)
@@ -30,7 +30,12 @@ struct N : M, P {
   P p;
 };
 
+struct O : B { 
+  ~O() { return; } 
+};
+
 int main() {
   N n1;
   N n2;
+  O o;
 }