]> granicus.if.org Git - clang/commitdiff
Don't emit derived-to-base destructor aliases if we don't have a definition
authorJohn McCall <rjmccall@apple.com>
Wed, 3 Mar 2010 03:40:11 +0000 (03:40 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 3 Mar 2010 03:40:11 +0000 (03:40 +0000)
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

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/destructors.cpp

index cb8489d20240e4170044fa22b242cb76960753ca..4889fc08f488912a313f848d75aff446482de13b 100644 (file)
@@ -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));
 }
index accd1b349867544fba2a313af8984a793fe58a0f..d40b174012ffc6371df4674180e795bc799afa39 100644 (file)
@@ -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
+}