Page MenuHomePhabricator

[Clang][CodeGen] set alias linkage on QualType
ClosedPublic

Authored by nickdesaulniers on Aug 20 2019, 12:42 PM.

Details

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

Diff Detail

Repository
rL LLVM

Event Timeline

nickdesaulniers edited the summary of this revision. (Show Details)Aug 20 2019, 12:50 PM
nickdesaulniers added a reviewer: aaron.ballman.
aaron.ballman accepted this revision.Aug 22 2019, 11:03 AM

I am not an expert on the alias attribute, but from what I can tell (with much thanks to @erichkeane for also helping to verify), this matches the GCC behavior. LGTM, but can you add a test for the function behavior as well?

This revision is now accepted and ready to land.Aug 22 2019, 11:03 AM
  • add unit test for function
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2019, 1:51 PM

I think this patch might be causing some test failures on our mac bots:

FAIL: Clang :: CodeGen/alias.c (2014 of 15397)
******************** TEST 'Clang :: CodeGen/alias.c' FAILED ********************
Script:
--
: 'RUN: at line 2';   /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/clang -cc1 -internal-isystem /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/lib/clang/10.0.0/include -nostdsysteminc -triple i386-pc-linux-gnu -emit-llvm -o - /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c | /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/FileCheck -check-prefix=CHECKBASIC /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c
: 'RUN: at line 3';   /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/clang -cc1 -internal-isystem /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/lib/clang/10.0.0/include -nostdsysteminc -triple armv7a-eabi -mfloat-abi hard -emit-llvm -o - /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c | /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/FileCheck -check-prefix=CHECKCC /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c
: 'RUN: at line 4';   /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/clang -cc1 -internal-isystem /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/lib/clang/10.0.0/include -nostdsysteminc -triple armv7a-eabi -mfloat-abi hard -S -o - /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c | /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/FileCheck -check-prefix=CHECKASM /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c
: 'RUN: at line 5';   /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/clang -cc1 -internal-isystem /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/lib/clang/10.0.0/include -nostdsysteminc -emit-llvm -o - /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c | /b/s/w/ir/k/recipe_cleanup/clangVieak_/llvm_build_dir/bin/FileCheck -check-prefix=CHECKGLOBALS /b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c
--
Exit Code: 2

Command Output (stderr):
--
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:87:33: warning: alias will always resolve to test8_bar even if weak definition of test8_foo is overridden
void test8_zed() __attribute__((alias("test8_foo")));
                                ^
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:90:37: warning: alias will not be in section 'test' but in the same section as the aliasee
void test9_zed(void) __attribute__((section("test")));
                                    ^
2 warnings generated.
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:87:33: warning: alias will always resolve to test8_bar even if weak definition of test8_foo is overridden
void test8_zed() __attribute__((alias("test8_foo")));
                                ^
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:90:37: warning: alias will not be in section 'test' but in the same section as the aliasee
void test9_zed(void) __attribute__((section("test")));
                                    ^
2 warnings generated.
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:87:33: warning: alias will always resolve to test8_bar even if weak definition of test8_foo is overridden
void test8_zed() __attribute__((alias("test8_foo")));
                                ^
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:90:37: warning: alias will not be in section 'test' but in the same section as the aliasee
void test9_zed(void) __attribute__((section("test")));
                                    ^
2 warnings generated.
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:24:57: error: aliases are not supported on darwin
extern const int __mod_usb_device_table __attribute__ ((alias("wacom_usb_ids")));
                                                        ^
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:31:28: error: aliases are not supported on darwin
extern int g1 __attribute((alias("g0")));
                           ^
/b/s/w/ir/k/llvm-project/clang/test/CodeGen/alias.c:37:50: error: aliases are not supported on darwin
extern __thread int __libc_errno __attribute__ ((alias ("TL_WITH_ALIAS")));
                                                 ^
... A bunch more like this

--

********************
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Testing Time: 126.01s
********************
Failing Tests (1):
    Clang :: CodeGen/alias.c

Could you take a look? Thanks.

@leonardchan thanks for the report, would you mind reviewing: https://reviews.llvm.org/D66622?

iajbar added a subscriber: iajbar.Oct 23 2020, 11:39 AM

Clang crashes when calling getLLVMLinkageVarDefinition() in EmitAliasDefinition() when compiling this testcase:
enum a_type { a , b, c};
typedef enum a_type b_type;
void foo(b_type x, enum a_type y){}
void bar(b_type x, enum b_type y) attribute ((alias ("foo")));

DeclTy is not set because of "enum b_type" is incomplete type. So calling getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),..) triggered an assert because GD.getDecl() is FunctionDecl.

Clang crashes when calling getLLVMLinkageVarDefinition() in EmitAliasDefinition() when compiling this testcase:
enum a_type { a , b, c};
typedef enum a_type b_type;
void foo(b_type x, enum a_type y){}
void bar(b_type x, enum b_type y) attribute ((alias ("foo")));

DeclTy is not set because of "enum b_type" is incomplete type. So calling getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),..) triggered an assert because GD.getDecl() is FunctionDecl.

Thanks for the report and concise test case; sorry for breaking your build! I'll take a look and CC you when I have a fix.

Clang crashes when calling getLLVMLinkageVarDefinition() in EmitAliasDefinition() when compiling this testcase:
enum a_type { a , b, c};
typedef enum a_type b_type;
void foo(b_type x, enum a_type y){}
void bar(b_type x, enum b_type y) attribute ((alias ("foo")));

DeclTy is not set because of "enum b_type" is incomplete type. So calling getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),..) triggered an assert because GD.getDecl() is FunctionDecl.

It's probably worth noting that the input is funny because enum b_type != b_type.

warning: declaration of 'enum b_type' will not be visible outside of this function [-Wvisibility]

Turns out, the enum and the typedef are red herrings. Because the types don't match we should be warning via -Wattribute-alias=1 that GCC has but we don't.

void test13(float y) {}
void test13_foo(int y) __attribute__((alias ("test13")));

GCC:

<source>:5:6: warning: 'test13_foo' alias between functions of incompatible types 'void(int)' and 'void(float)' [-Wattribute-alias=]

We should still not crash. I don't plan on implementing -Wattribute-alias= today, but will try to fix up the crash.
https://bugs.llvm.org/show_bug.cgi?id=47957 for the feature request.
https://reviews.llvm.org/D90073