diff options
author | Alexis Hunt <alercah@gmail.com> | 2011-05-03 23:05:34 +0000 |
---|---|---|
committer | Alexis Hunt <alercah@gmail.com> | 2011-05-03 23:05:34 +0000 |
commit | 9d47faf686b8ef02d1f5511eb53972a89ce0d3d8 (patch) | |
tree | 7ade35f5c70e5608ac5e7af7e8c509ed987fe108 /clang/lib/CodeGen/CGClass.cpp | |
parent | fd7ff20575e3fc541b9d0143905472a17c546741 (diff) | |
download | bcm5719-llvm-9d47faf686b8ef02d1f5511eb53972a89ce0d3d8.tar.gz bcm5719-llvm-9d47faf686b8ef02d1f5511eb53972a89ce0d3d8.zip |
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).
llvm-svn: 130803
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 12946423adf..cb410087138 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/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, |