aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorSean Hunt <scshunt@csclub.uwaterloo.ca>2011-05-03 23:05:34 +0000
committerSean Hunt <scshunt@csclub.uwaterloo.ca>2011-05-03 23:05:34 +0000
commitb76af9c969558b4484be87933e89e76e7ee87e21 (patch)
tree7310c9eea92bc2174544d955df89b4912cab77a2 /lib/CodeGen/CGClass.cpp
parentcc0f9f1a3b5df7fd308ff3d800fbbbbff805157d (diff)
Ensure that destructors are properly inovked when an exception leaves
the body of a delegating constructor call. This means that the delegating constructor implementation should be complete and correct, though there are some rough edges (diagnostic quality with the cycle detection and using a deleted destructor). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130803 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 12946423ad..cb41008713 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1270,6 +1270,23 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
ReturnValueSlot(), DelegateArgs, Ctor);
}
+namespace {
+ struct CallDelegatingCtorDtor : EHScopeStack::Cleanup {
+ const CXXDestructorDecl *Dtor;
+ llvm::Value *Addr;
+ CXXDtorType Type;
+
+ CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr,
+ CXXDtorType Type)
+ : Dtor(D), Addr(Addr), Type(Type) {}
+
+ void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
+ Addr);
+ }
+ };
+}
+
void
CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
const FunctionArgList &Args) {
@@ -1280,8 +1297,17 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor
AggValueSlot AggSlot = AggValueSlot::forAddr(ThisPtr, false, /*Lifetime*/ true);
EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
-}
+ const CXXRecordDecl *ClassDecl = Ctor->getParent();
+ if (CGM.getLangOptions().Exceptions && !ClassDecl->hasTrivialDestructor()) {
+ CXXDtorType Type =
+ CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base;
+
+ EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup,
+ ClassDecl->getDestructor(),
+ ThisPtr, Type);
+ }
+}
void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
CXXDtorType Type,