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