diff options
author | John McCall <rjmccall@apple.com> | 2013-02-01 05:11:40 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-02-01 05:11:40 +0000 |
commit | 074cae0861a87bf96d8ea56d02e34839d9ccbd0a (patch) | |
tree | a75e3a668f4ebae4ffeaa83a0cc11606862df0f0 /lib/CodeGen/CGClass.cpp | |
parent | 10318845f40d50b9d0ce010b0ea8d93a7b5ab029 (diff) |
Destroy arrays and ARC fields when throwing out of ctors.
Previously we were only handling non-array fields of class type.
Testcases derived from a patch by WenHan Gu.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174146 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 36 |
1 files changed, 6 insertions, 30 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 0611ed7834..ce32acd0da 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -532,21 +532,6 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, CGF.EmitBlock(AfterFor, true); } -namespace { - struct CallMemberDtor : EHScopeStack::Cleanup { - llvm::Value *V; - CXXDestructorDecl *Dtor; - - CallMemberDtor(llvm::Value *V, CXXDestructorDecl *Dtor) - : V(V), Dtor(Dtor) {} - - void Emit(CodeGenFunction &CGF, Flags flags) { - CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, - /*Delegating=*/false, V); - } - }; -} - static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, @@ -652,22 +637,13 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, ArrayIndexes, 0); - - if (!CGM.getLangOpts().Exceptions) - return; - - // FIXME: If we have an array of classes w/ non-trivial destructors, - // we need to destroy in reverse order of construction along the exception - // path. - const RecordType *RT = FieldType->getAs<RecordType>(); - if (!RT) - return; - - CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - if (!RD->hasTrivialDestructor()) - EHStack.pushCleanup<CallMemberDtor>(EHCleanup, LHS.getAddress(), - RD->getDestructor()); } + + // Ensure that we destroy this object if an exception is thrown + // later in the constructor. + QualType::DestructionKind dtorKind = FieldType.isDestructedType(); + if (needsEHCleanup(dtorKind)) + pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); } /// Checks whether the given constructor is a valid subject for the |