[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:
Nick Desaulniers 2019-08-22 20:47:12 +00:00
parent 2eaeba6f15
commit f21bca02f7
2 changed files with 20 additions and 4 deletions

View File

@ -4363,17 +4363,22 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
// Create a reference to the named value. This ensures that it is emitted
// if a deferred decl.
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
llvm::GlobalValue::LinkageTypes LT;
if (isa<llvm::FunctionType>(DeclTy)) {
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD,
/*ForVTable=*/false);
else
LT = getFunctionLinkage(GD);
} else {
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
llvm::PointerType::getUnqual(DeclTy),
/*D=*/nullptr);
LT = getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),
D->getType().isConstQualified());
}
// Create the new alias itself, but don't set a name yet.
auto *GA = llvm::GlobalAlias::create(
DeclTy, 0, llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
auto *GA =
llvm::GlobalAlias::create(DeclTy, 0, LT, "", Aliasee, &getModule());
if (Entry) {
if (GA->getAliasee() == Entry) {

View File

@ -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 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 -emit-llvm -o - %s | FileCheck -check-prefix=CHECKGLOBALS %s
int g0;
// CHECKBASIC-DAG: @g0 = common global i32 0
@ -88,3 +89,13 @@ void test8_zed() __attribute__((alias("test8_foo")));
void test9_bar(void) { }
void test9_zed(void) __attribute__((section("test")));
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")));