summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp26
-rw-r--r--clang/test/CodeGenCXX/ctor-dtor-alias.cpp15
2 files changed, 28 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index f9b07d2386b..f79e079745c 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -82,18 +82,12 @@ 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();
- if (!BaseD->isImplicit() && !BaseD->hasBody())
- return true;
-
// If the base is at a non-zero offset, give up.
const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class);
if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero())
return true;
+ const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
GlobalDecl(BaseD, Dtor_Base),
false);
@@ -146,14 +140,20 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
return false;
}
- // Don't create an alias to a linker weak symbol unless we know we can do
- // that in every TU. This avoids producing different COMDATs in different
- // TUs.
- if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) {
- if (!InEveryTU)
+ if (!InEveryTU) {
+ /// 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.
+ if (Ref->isDeclaration())
return true;
- assert(Linkage == TargetLinkage);
+ // Don't create an alias to a linker weak symbol unless we know we can do
+ // that in every TU. This avoids producing different COMDATs in different
+ // TUs.
+ if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) {
+ assert(Linkage == TargetLinkage);
+ return true;
+ }
}
// Create the alias with no name.
diff --git a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
index 6e1c144e5de..745495ac68f 100644
--- a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -73,3 +73,18 @@ namespace test5 {
}
B X;
}
+
+namespace test6 {
+ // Test that we use ~A directly, even when ~A is not defined. The symbol for
+ // ~B would have been internal and still contain a reference to ~A.
+ struct A {
+ virtual ~A();
+ };
+ namespace {
+ struct B : public A {
+ ~B() {}
+ };
+ }
+ B X;
+ // CHECK-DAG: call i32 @__cxa_atexit({{.*}}@_ZN5test61AD2Ev
+}
OpenPOWER on IntegriCloud