forked from OSchip/llvm-project
[Clang][CodeGen] set alias linkage on QualType
Summary: It seems that CodeGen was always using ExternalLinkage when emitting a GlobalDecl with __attribute__((alias)). This leads to symbol redefinitions (ODR) that cause failures at link time for static aliases. This is readily attempting to link an ARM (32b) allyesconfig Linux kernel built with Clang. Reported-by: nathanchance Suggested-by: ihalip Link: https://bugs.llvm.org/show_bug.cgi?id=42377 Link: https://github.com/ClangBuiltLinux/linux/issues/631 Reviewers: rsmith, aaron.ballman, erichkeane Reviewed By: aaron.ballman Subscribers: javed.absar, kristof.beyls, cfe-commits, srhines, ihalip, nathanchance Tags: #clang Differential Revision: https://reviews.llvm.org/D66492 llvm-svn: 369705
This commit is contained in:
parent
2eaeba6f15
commit
f21bca02f7
|
@ -4363,17 +4363,22 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||||
// Create a reference to the named value. This ensures that it is emitted
|
// Create a reference to the named value. This ensures that it is emitted
|
||||||
// if a deferred decl.
|
// if a deferred decl.
|
||||||
llvm::Constant *Aliasee;
|
llvm::Constant *Aliasee;
|
||||||
if (isa<llvm::FunctionType>(DeclTy))
|
llvm::GlobalValue::LinkageTypes LT;
|
||||||
|
if (isa<llvm::FunctionType>(DeclTy)) {
|
||||||
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD,
|
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD,
|
||||||
/*ForVTable=*/false);
|
/*ForVTable=*/false);
|
||||||
else
|
LT = getFunctionLinkage(GD);
|
||||||
|
} else {
|
||||||
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||||
llvm::PointerType::getUnqual(DeclTy),
|
llvm::PointerType::getUnqual(DeclTy),
|
||||||
/*D=*/nullptr);
|
/*D=*/nullptr);
|
||||||
|
LT = getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),
|
||||||
|
D->getType().isConstQualified());
|
||||||
|
}
|
||||||
|
|
||||||
// Create the new alias itself, but don't set a name yet.
|
// Create the new alias itself, but don't set a name yet.
|
||||||
auto *GA = llvm::GlobalAlias::create(
|
auto *GA =
|
||||||
DeclTy, 0, llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
|
llvm::GlobalAlias::create(DeclTy, 0, LT, "", Aliasee, &getModule());
|
||||||
|
|
||||||
if (Entry) {
|
if (Entry) {
|
||||||
if (GA->getAliasee() == Entry) {
|
if (GA->getAliasee() == Entry) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECKBASIC %s
|
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECKBASIC %s
|
||||||
// RUN: %clang_cc1 -triple armv7a-eabi -mfloat-abi hard -emit-llvm -o - %s | FileCheck -check-prefix=CHECKCC %s
|
// RUN: %clang_cc1 -triple armv7a-eabi -mfloat-abi hard -emit-llvm -o - %s | FileCheck -check-prefix=CHECKCC %s
|
||||||
// RUN: %clang_cc1 -triple armv7a-eabi -mfloat-abi hard -S -o - %s | FileCheck -check-prefix=CHECKASM %s
|
// RUN: %clang_cc1 -triple armv7a-eabi -mfloat-abi hard -S -o - %s | FileCheck -check-prefix=CHECKASM %s
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=CHECKGLOBALS %s
|
||||||
|
|
||||||
int g0;
|
int g0;
|
||||||
// CHECKBASIC-DAG: @g0 = common global i32 0
|
// CHECKBASIC-DAG: @g0 = common global i32 0
|
||||||
|
@ -88,3 +89,13 @@ void test8_zed() __attribute__((alias("test8_foo")));
|
||||||
void test9_bar(void) { }
|
void test9_bar(void) { }
|
||||||
void test9_zed(void) __attribute__((section("test")));
|
void test9_zed(void) __attribute__((section("test")));
|
||||||
void test9_zed(void) __attribute__((alias("test9_bar")));
|
void test9_zed(void) __attribute__((alias("test9_bar")));
|
||||||
|
|
||||||
|
// Test that the alias gets its linkage from its declared qual type.
|
||||||
|
// CHECKGLOBALS: @test10_foo = internal
|
||||||
|
// CHECKGLOBALS-NOT: @test10_foo = dso_local
|
||||||
|
int test10;
|
||||||
|
static int test10_foo __attribute__((alias("test10")));
|
||||||
|
// CHECKGLOBALS: @test11_foo = internal
|
||||||
|
// CHECKGLOBALS-NOT: @test11_foo = dso_local
|
||||||
|
void test11(void) {}
|
||||||
|
static void test11_foo(void) __attribute__((alias("test11")));
|
||||||
|
|
Loading…
Reference in New Issue