forked from OSchip/llvm-project
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
This commit is contained in:
parent
c8e4bd156b
commit
129d313c8d
|
@ -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());
|
||||
|
|
|
@ -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() {}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue