Don't emit derived-to-base destructor aliases if we don't have a definition

for the base destructor, because aliases to declarations aren't legal.

Fixes PR 6471.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97637 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2010-03-03 03:40:11 +00:00
Родитель 89b7702c9a
Коммит 9a70846c5f
2 изменённых файлов: 21 добавлений и 1 удалений

Просмотреть файл

@ -93,12 +93,18 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
if (!UniqueBase)
return true;
/// If we don't have a definition for the destructor yet, don't
/// emit. We can't emit aliases to declarations; that's just not
/// how aliases work.
const CXXDestructorDecl *BaseD = UniqueBase->getDestructor(getContext());
if (!BaseD->isImplicit() && !BaseD->getBody())
return true;
// If the base is at a non-zero offset, give up.
const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class);
if (ClassLayout.getBaseClassOffset(UniqueBase) != 0)
return true;
const CXXDestructorDecl *BaseD = UniqueBase->getDestructor(getContext());
return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
GlobalDecl(BaseD, Dtor_Base));
}

Просмотреть файл

@ -104,6 +104,10 @@ namespace test1 {
struct Empty { }; // trivial destructor, empty
struct NonEmpty { int x; }; // trivial destructor, non-empty
// There must be a definition in this translation unit for the alias
// optimization to apply.
A::~A() { delete m; }
struct M : A { ~M(); };
M::~M() {} // alias tested above
@ -133,3 +137,13 @@ namespace test1 {
struct U : A, virtual B { ~U(); };
U::~U() {} // CHECK: define void @_ZN5test11UD2Ev
}
// PR6471
namespace test2 {
struct A { ~A(); char ***m; };
struct B : A { ~B(); };
B::~B() {}
// CHECK: define void @_ZN5test21BD2Ev
// CHECK: call void @_ZN5test21AD2Ev
}