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