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