1// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s 2 3// CHECK: @weakvar = weak global 4// CHECK: @__weakvar_alias = common global 5// CHECK: @correct_linkage = weak global 6 7 8// CHECK: @both = alias void ()* @__both 9// CHECK: @both2 = alias void ()* @__both2 10// CHECK: @both3 = alias weak void ()* @__both3 11// CHECK: @a3 = alias weak void ()* @__a3 12// CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias 13// CHECK: @foo = alias weak void ()* @__foo 14// CHECK: @foo2 = alias weak void ()* @__foo2 15// CHECK: @stutter = alias weak void ()* @__stutter 16// CHECK: @stutter2 = alias weak void ()* @__stutter2 17// CHECK: @declfirst = alias weak void ()* @__declfirst 18// CHECK: @declfirstattr = alias weak void ()* @__declfirstattr 19// CHECK: @mix2 = alias weak void ()* @__mix2 20// CHECK: @a1 = alias weak void ()* @__a1 21// CHECK: @xxx = alias weak void ()* @__xxx 22 23 24 25// CHECK: define weak void @weakdef() 26 27 28#pragma weak weakvar 29int weakvar; 30 31#pragma weak weakdef 32void weakdef(void) {} 33 34#pragma weak param // expected-warning {{weak identifier 'param' never declared}} 35#pragma weak correct_linkage 36void f(int param) { 37 int correct_linkage; 38} 39 40#pragma weak weakvar_alias = __weakvar_alias 41int __weakvar_alias; 42 43#pragma weak foo = __foo 44void __foo(void) {} 45// CHECK: define void @__foo() 46 47 48void __foo2(void) {} 49#pragma weak foo2 = __foo2 50// CHECK: define void @__foo2() 51 52 53///// test errors 54 55#pragma weak unused // expected-warning {{weak identifier 'unused' never declared}} 56#pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}} 57 58#pragma weak td // expected-warning {{weak identifier 'td' never declared}} 59typedef int td; 60 61#pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}} 62typedef int __td2; 63 64 65///// test weird cases 66 67// test repeats 68 69#pragma weak stutter = __stutter 70#pragma weak stutter = __stutter 71void __stutter(void) {} 72// CHECK: define void @__stutter() 73 74void __stutter2(void) {} 75#pragma weak stutter2 = __stutter2 76#pragma weak stutter2 = __stutter2 77// CHECK: define void @__stutter2() 78 79 80// test decl/pragma weak order 81 82void __declfirst(void); 83#pragma weak declfirst = __declfirst 84void __declfirst(void) {} 85// CHECK: define void @__declfirst() 86 87void __declfirstattr(void) __attribute((noinline)); 88#pragma weak declfirstattr = __declfirstattr 89void __declfirstattr(void) {} 90// CHECK: define void @__declfirstattr() 91 92//// test that other attributes are preserved 93 94//// ensure that pragma weak/__attribute((weak)) play nice 95 96void mix(void); 97#pragma weak mix 98__attribute((weak)) void mix(void) { } 99// CHECK: define weak void @mix() 100 101// ensure following __attributes are preserved and that only a single 102// alias is generated 103#pragma weak mix2 = __mix2 104void __mix2(void) __attribute((noinline)); 105void __mix2(void) __attribute((noinline)); 106void __mix2(void) {} 107// CHECK: define void @__mix2() 108 109////////////// test #pragma weak/__attribute combinations 110 111// if the SAME ALIAS is already declared then it overrides #pragma weak 112// resulting in a non-weak alias in this case 113void both(void) __attribute((alias("__both"))); 114#pragma weak both = __both 115void __both(void) {} 116// CHECK: define void @__both() 117 118// if the TARGET is previously declared then whichever aliasing method 119// comes first applies and subsequent aliases are discarded. 120// TODO: warn about this 121 122void __both2(void); 123void both2(void) __attribute((alias("__both2"))); // first, wins 124#pragma weak both2 = __both2 125void __both2(void) {} 126// CHECK: define void @__both2() 127 128void __both3(void); 129#pragma weak both3 = __both3 // first, wins 130void both3(void) __attribute((alias("__both3"))); 131void __both3(void) {} 132// CHECK: define void @__both3() 133 134///////////// ensure that #pragma weak does not alter existing __attributes() 135 136void __a1(void) __attribute((noinline)); 137#pragma weak a1 = __a1 138void __a1(void) {} 139// CHECK: define void @__a1() {{.*}} noinline 140 141// attributes introduced BEFORE a combination of #pragma weak and alias() 142// hold... 143void __a3(void) __attribute((noinline)); 144#pragma weak a3 = __a3 145void a3(void) __attribute((alias("__a3"))); 146void __a3(void) {} 147// CHECK: define void @__a3() {{.*}} noinline 148 149#pragma weak xxx = __xxx 150__attribute((pure,noinline,const,fastcall)) void __xxx(void) { } 151// CHECK: void @__xxx() {{.*}} noinline 152 153///////////// PR10878: Make sure we can call a weak alias 154void SHA512Pad(void *context) {} 155#pragma weak SHA384Pad = SHA512Pad 156void PR10878() { SHA384Pad(0); } 157// CHECK: call void @SHA384Pad(i8* null) 158 159 160///////////// TODO: stuff that still doesn't work 161 162// due to the fact that disparate TopLevelDecls cannot affect each other 163// (due to clang's Parser and ASTConsumer behavior, and quite reasonable) 164// #pragma weak must appear before or within the same TopLevelDecl as it 165// references. 166void yyy(void){} 167void zzz(void){} 168#pragma weak yyy 169// NOTE: weak doesn't apply, not before or in same TopLevelDec(!) 170// CHECK: define void @yyy() 171 172int correct_linkage; 173