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