xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/pragma-weak.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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