forked from OSchip/llvm-project
Alias must point to a definition
Reapplying the patch after modifying the test case. Inlining the destructor caused the compiler to generate bad IR which failed the Verifier in the backend. https://llvm.org/bugs/show_bug.cgi?id=30341 This patch disables alias to available_externally definitions. Reviewers: eugenis, rsmith Differential Revision: https://reviews.llvm.org/D24682 llvm-svn: 283063
This commit is contained in:
parent
f230b0aa43
commit
e84372b039
|
@ -134,6 +134,11 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
|||
llvm::GlobalValue::LinkageTypes TargetLinkage =
|
||||
getFunctionLinkage(TargetDecl);
|
||||
|
||||
// available_externally definitions aren't real definitions, so we cannot
|
||||
// create an alias to one.
|
||||
if (TargetLinkage == llvm::GlobalValue::AvailableExternallyLinkage)
|
||||
return true;
|
||||
|
||||
// Check if we have it already.
|
||||
StringRef MangledName = getMangledName(AliasDecl);
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
|
@ -156,14 +161,7 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
|||
|
||||
// Instead of creating as alias to a linkonce_odr, replace all of the uses
|
||||
// of the aliasee.
|
||||
if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) &&
|
||||
(TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage ||
|
||||
!TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) {
|
||||
// FIXME: An extern template instantiation 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.
|
||||
if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) {
|
||||
addReplacement(MangledName, Aliasee);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %clang_cc1 -O1 -std=c++11 -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
|
||||
// Clang should not generate alias to available_externally definitions.
|
||||
// Check that the destructor of Foo is defined.
|
||||
// The destructors have different return type for different targets.
|
||||
// CHECK: define linkonce_odr {{.*}} @_ZN3FooD2Ev
|
||||
template <class CharT>
|
||||
struct String {
|
||||
String() {}
|
||||
~String();
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline __attribute__((visibility("hidden"), always_inline))
|
||||
String<CharT>::~String() {}
|
||||
|
||||
extern template struct String<char>;
|
||||
|
||||
struct Foo : public String<char> { Foo() { String<char> s; } };
|
||||
|
||||
Foo f;
|
Loading…
Reference in New Issue