From a1cbab0992993189aa1d67fa6b1bcf47e5fe12c0 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger <joerg@bec.de> Date: Fri, 22 Nov 2013 21:34:35 +0000 Subject: [PATCH] Adjust r194296 to not apply the alias replacement for externally available always-inline functions. This breaks libc++'s locale implementation. Code generation for this case should be fixed, but this is a stop gap fix for clang 3.4. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195501 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 9 +++++++- test/CodeGenCXX/ctor-dtor-alias.cpp | 32 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 22baa654084..cfb2d6291b8 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -140,7 +140,14 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, // Instead of creating as alias to a linkonce_odr, replace all of the uses // of the aliassee. - if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) { + if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && + (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage || + !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { + // FIXME: An extern template instanciation will create functions with + // linkage "AvailableExternally". In libc++, some classes also define + // members with attribute "AlwaysInline" and expect no reference to + // be generated. It is desirable to reenable this optimisation after + // corresponding LLVM changes. Replacements[MangledName] = Aliasee; return false; } diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp index 6efd0bf9f87..235d1650dec 100644 --- a/test/CodeGenCXX/ctor-dtor-alias.cpp +++ b/test/CodeGenCXX/ctor-dtor-alias.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s // RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s +// RUN: %clang_cc1 -cc1 -triple x86_64--netbsd -emit-llvm \ +// RUN: -mconstructor-aliases -O2 %s -o - | FileCheck --check-prefix=CHECK-RAUW %s + namespace test1 { // 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 @@ -129,3 +132,32 @@ namespace test8 { struct zed : public bar {}; zed foo; } + +// CHECK-RAUW: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}] +// r194296 replaced C::~C with B::~B without emitting the later. + +class A { +public: + A(int); + virtual ~A(); +}; + +template <class> +class B : A { +public: + B() + : A(0) { + } + __attribute__((always_inline)) ~B() { + } +}; + +extern template class B<char>; + +class C : B<char> { +}; + +void +fn1() { + new C; +} -- GitLab