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