summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-11-12 22:06:46 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-11-12 22:06:46 +0000
commit129d313c8d133218f142e77ce89dd5e19e5feb75 (patch)
tree82b5e755c040468b4af47f97afbe2316a19a1b7e
parentc8e4bd156b514af6ac920a53c2a5a28d169b7d6b (diff)
downloadbcm5719-llvm-129d313c8d133218f142e77ce89dd5e19e5feb75.tar.gz
bcm5719-llvm-129d313c8d133218f142e77ce89dd5e19e5feb75.zip
Avoid producing mismatched comdats.
The problem was that given template<typename T> struct foo { ~foo() {} }; template class foo<int>; We would produce a alias, creating a comdat with D0 and D1, since the symbols have to be weak. Another TU is not required to have a explicit template instantiation definition or an explict template instantiation declaration and for template<typename T> struct foo { ~foo() {} }; foo<int> a; we would produce a comdat with only one symbol in it. llvm-svn: 194520
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp13
-rw-r--r--clang/test/CodeGenCXX/ctor-dtor-alias.cpp10
2 files changed, 14 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 0f55616ea6b..b16c59d5f65 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -146,14 +146,15 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
/// how aliases work.
if (Ref->isDeclaration())
return true;
-
- // 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))
- return true;
}
+ // Don't create an alias to a linker weak symbol. This avoids producing
+ // different COMDATs in different TUs. Another option would be to
+ // output the alias both for weak_odr and linkonce_odr, but that
+ // requires explicit comdat support in the IL.
+ if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
+ return true;
+
// Create the alias with no name.
llvm::GlobalAlias *Alias =
new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
diff --git a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
index ef56564d3dd..266eecc8093 100644
--- a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,10 +1,14 @@
// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases | FileCheck %s
namespace test1 {
-// test that we produce an alias when the destructor is weak_odr
+// test that we don't produce an alias when the destructor is weak_odr. The
+// reason to avoid it that another TU might have no explicit template
+// instantiation definition or declaration, causing it to to output only
+// one of the destructors as linkonce_odr, producing a different comdat.
+
+// CHECK-DAG: define weak_odr void @_ZN5test16foobarIvEC2Ev
+// CHECK-DAG: define weak_odr void @_ZN5test16foobarIvEC1Ev
-// CHECK-DAG: @_ZN5test16foobarIvEC1Ev = alias weak_odr void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvEC2Ev
-// CHECK-DAG: define weak_odr void @_ZN5test16foobarIvEC2Ev(
template <typename T> struct foobar {
foobar() {}
};
OpenPOWER on IntegriCloud