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