Skip to content

Commit

Permalink
Alias must point to a definition
Browse files Browse the repository at this point in the history
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
  • Loading branch information
hiraditya committed Oct 2, 2016
1 parent f230b0a commit e84372b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
14 changes: 6 additions & 8 deletions clang/lib/CodeGen/CGCXX.cpp
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions clang/test/CodeGenCXX/alias-available-externally.cpp
@@ -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;

0 comments on commit e84372b

Please sign in to comment.