]> granicus.if.org Git - clang/commitdiff
[Clang][CodeGen] set alias linkage on QualType
authorNick Desaulniers <ndesaulniers@google.com>
Thu, 22 Aug 2019 20:47:12 +0000 (20:47 +0000)
committerNick Desaulniers <ndesaulniers@google.com>
Thu, 22 Aug 2019 20:47:12 +0000 (20:47 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369705 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/alias.c

index 0f7ac2a20239b06a9d2db7f8b600629b4aacfa09..3dc40a84868f873be53b0685f48e45855c94da31 100644 (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) {
index 78b020454a9fa778fe28c280c0695c0a7d5dcfd0..296a707c44bd831345c4762ede5776ceebbbee0d 100644 (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")));