From 610616c279681aa195cdf63b6472bc811e7d75a0 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 12 Nov 2013 22:06:46 +0000 Subject: [PATCH] Avoid producing mismatched comdats. The problem was that given template struct foo { ~foo() {} }; template class foo; 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 struct foo { ~foo() {} }; foo a; we would produce a comdat with only one symbol in it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 13 +++++++------ test/CodeGenCXX/ctor-dtor-alias.cpp | 10 +++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 0f55616ea6..b16c59d5f6 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/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/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp index ef56564d3d..266eecc809 100644 --- a/test/CodeGenCXX/ctor-dtor-alias.cpp +++ b/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 struct foobar { foobar() {} }; -- 2.40.0