Re-enable the fix for PR9181 now that all the edge cases are handled.

llvm-svn: 131385
This commit is contained in:
Anders Carlsson
2011-05-15 17:36:21 +00:00
parent 2f10078ae7
commit 49c0bd2a25
3 changed files with 152 additions and 21 deletions

View File

@@ -741,14 +741,78 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args);
}
static bool
FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
static bool
HasTrivialDestructorBody(ASTContext &Context,
const CXXRecordDecl *BaseClassDecl,
const CXXRecordDecl *MostDerivedClassDecl)
{
// If the destructor is trivial we don't have to check anything else.
if (BaseClassDecl->hasTrivialDestructor())
return true;
if (!BaseClassDecl->getDestructor()->hasTrivialBody())
return false;
// Check fields.
for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(),
E = BaseClassDecl->field_end(); I != E; ++I) {
const FieldDecl *Field = *I;
if (!FieldHasTrivialDestructorBody(Context, Field))
return false;
}
// Check non-virtual bases.
for (CXXRecordDecl::base_class_const_iterator I =
BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end();
I != E; ++I) {
if (I->isVirtual())
continue;
const CXXRecordDecl *NonVirtualBase =
cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
if (!HasTrivialDestructorBody(Context, NonVirtualBase,
MostDerivedClassDecl))
return false;
}
if (BaseClassDecl == MostDerivedClassDecl) {
// Check virtual bases.
for (CXXRecordDecl::base_class_const_iterator I =
BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end();
I != E; ++I) {
const CXXRecordDecl *VirtualBase =
cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
if (!HasTrivialDestructorBody(Context, VirtualBase,
MostDerivedClassDecl))
return false;
}
}
return true;
}
static bool
FieldHasTrivialDestructorBody(ASTContext &Context,
const FieldDecl *Field)
{
QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
if (!RT)
return true;
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
}
/// CanSkipVTablePointerInitialization - Check whether we need to initialize
/// any vtable pointers before calling this destructor.
static bool CanSkipVTablePointerInitialization(ASTContext &Context,
const CXXDestructorDecl *Dtor) {
// FIXME: We need to check dtors of bases of members too.
// Re-enable once this has been fixed.
return false;
if (!Dtor->hasTrivialBody())
return false;
@@ -757,21 +821,9 @@ static bool CanSkipVTablePointerInitialization(ASTContext &Context,
for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
E = ClassDecl->field_end(); I != E; ++I) {
const FieldDecl *Field = *I;
QualType FieldBaseElementType =
Context.getBaseElementType(Field->getType());
const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
if (!RT)
continue;
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
if (FieldClassDecl->hasTrivialDestructor())
continue;
if (FieldClassDecl->getDestructor()->hasTrivialBody())
continue;
return false;
if (!FieldHasTrivialDestructorBody(Context, Field))
return false;
}
return true;