1 | // RUN: %clang_cc1 %s -verify -ffreestanding -fsyntax-only -triple=i686-linux-gnu -std=c11 -Watomic-implicit-seq-cst |
2 | |
3 | // _Atomic operations are implicitly sequentially-consistent. Some codebases |
4 | // want to force explicit usage of memory order instead. |
5 | |
6 | _Atomic(int) atom; |
7 | void gimme_int(int); |
8 | |
9 | void bad_pre_inc(void) { |
10 | ++atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
11 | } |
12 | |
13 | void bad_pre_dec(void) { |
14 | --atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
15 | } |
16 | |
17 | void bad_post_inc(void) { |
18 | atom++; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
19 | } |
20 | |
21 | void bad_post_dec(void) { |
22 | atom--; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
23 | } |
24 | |
25 | void bad_call(void) { |
26 | gimme_int(atom); // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
27 | } |
28 | |
29 | int bad_unary_plus(void) { |
30 | return +atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
31 | } |
32 | |
33 | int bad_unary_minus(void) { |
34 | return -atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
35 | } |
36 | |
37 | int bad_unary_logical_not(void) { |
38 | return !atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
39 | } |
40 | |
41 | int bad_unary_bitwise_not(void) { |
42 | return ~atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
43 | } |
44 | |
45 | int bad_explicit_cast(void) { |
46 | return (int)atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
47 | } |
48 | |
49 | int bad_implicit_cast(void) { |
50 | return atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
51 | } |
52 | |
53 | int bad_mul_1(int i) { |
54 | return atom * i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
55 | } |
56 | |
57 | int bad_mul_2(int i) { |
58 | return i * atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
59 | } |
60 | |
61 | int bad_div_1(int i) { |
62 | return atom / i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
63 | } |
64 | |
65 | int bad_div_2(int i) { |
66 | return i / atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
67 | } |
68 | |
69 | int bad_mod_1(int i) { |
70 | return atom % i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
71 | } |
72 | |
73 | int bad_mod_2(int i) { |
74 | return i % atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
75 | } |
76 | |
77 | int bad_add_1(int i) { |
78 | return atom + i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
79 | } |
80 | |
81 | int bad_add_2(int i) { |
82 | return i + atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
83 | } |
84 | |
85 | int bad_sub_1(int i) { |
86 | return atom - i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
87 | } |
88 | |
89 | int bad_sub_2(int i) { |
90 | return i - atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
91 | } |
92 | |
93 | int bad_shl_1(int i) { |
94 | return atom << i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
95 | } |
96 | |
97 | int bad_shl_2(int i) { |
98 | return i << atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
99 | } |
100 | |
101 | int bad_shr_1(int i) { |
102 | return atom >> i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
103 | } |
104 | |
105 | int bad_shr_2(int i) { |
106 | return i >> atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
107 | } |
108 | |
109 | int bad_lt_1(int i) { |
110 | return atom < i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
111 | } |
112 | |
113 | int bad_lt_2(int i) { |
114 | return i < atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
115 | } |
116 | |
117 | int bad_le_1(int i) { |
118 | return atom <= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
119 | } |
120 | |
121 | int bad_le_2(int i) { |
122 | return i <= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
123 | } |
124 | |
125 | int bad_gt_1(int i) { |
126 | return atom > i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
127 | } |
128 | |
129 | int bad_gt_2(int i) { |
130 | return i > atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
131 | } |
132 | |
133 | int bad_ge_1(int i) { |
134 | return atom >= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
135 | } |
136 | |
137 | int bad_ge_2(int i) { |
138 | return i >= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
139 | } |
140 | |
141 | int bad_eq_1(int i) { |
142 | return atom == i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
143 | } |
144 | |
145 | int bad_eq_2(int i) { |
146 | return i == atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
147 | } |
148 | |
149 | int bad_ne_1(int i) { |
150 | return atom != i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
151 | } |
152 | |
153 | int bad_ne_2(int i) { |
154 | return i != atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
155 | } |
156 | |
157 | int bad_bitand_1(int i) { |
158 | return atom & i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
159 | } |
160 | |
161 | int bad_bitand_2(int i) { |
162 | return i & atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
163 | } |
164 | |
165 | int bad_bitxor_1(int i) { |
166 | return atom ^ i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
167 | } |
168 | |
169 | int bad_bitxor_2(int i) { |
170 | return i ^ atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
171 | } |
172 | |
173 | int bad_bitor_1(int i) { |
174 | return atom | i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
175 | } |
176 | |
177 | int bad_bitor_2(int i) { |
178 | return i | atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
179 | } |
180 | |
181 | int bad_and_1(int i) { |
182 | return atom && i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
183 | } |
184 | |
185 | int bad_and_2(int i) { |
186 | return i && atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
187 | } |
188 | |
189 | int bad_or_1(int i) { |
190 | return atom || i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
191 | } |
192 | |
193 | int bad_or_2(int i) { |
194 | return i || atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
195 | } |
196 | int bad_ternary_1(int i, int j) { |
197 | return i ? atom : j; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
198 | } |
199 | |
200 | int bad_ternary_2(int i, int j) { |
201 | return atom ? i : j; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
202 | } |
203 | |
204 | int bad_ternary_3(int i, int j) { |
205 | return i ? j : atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
206 | } |
207 | |
208 | void bad_assign_1(int i) { |
209 | atom = i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
210 | } |
211 | |
212 | void bad_assign_2(int *i) { |
213 | *i = atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
214 | } |
215 | |
216 | void bad_assign_3() { |
217 | atom = atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
218 | } |
219 | |
220 | void bad_compound_add_1(int i) { |
221 | atom += i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
222 | } |
223 | |
224 | void bad_compound_add_2(int *i) { |
225 | *i += atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
226 | } |
227 | |
228 | void bad_compound_sub_1(int i) { |
229 | atom -= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
230 | } |
231 | |
232 | void bad_compound_sub_2(int *i) { |
233 | *i -= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
234 | } |
235 | |
236 | void bad_compound_mul_1(int i) { |
237 | atom *= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
238 | } |
239 | |
240 | void bad_compound_mul_2(int *i) { |
241 | *i *= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
242 | } |
243 | |
244 | void bad_compound_div_1(int i) { |
245 | atom /= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
246 | } |
247 | |
248 | void bad_compound_div_2(int *i) { |
249 | *i /= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
250 | } |
251 | |
252 | void bad_compound_mod_1(int i) { |
253 | atom %= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
254 | } |
255 | |
256 | void bad_compound_mod_2(int *i) { |
257 | *i %= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
258 | } |
259 | |
260 | void bad_compound_shl_1(int i) { |
261 | atom <<= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
262 | } |
263 | |
264 | void bad_compound_shl_2(int *i) { |
265 | *i <<= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
266 | } |
267 | |
268 | void bad_compound_shr_1(int i) { |
269 | atom >>= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
270 | } |
271 | |
272 | void bad_compound_shr_2(int *i) { |
273 | *i >>= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
274 | } |
275 | |
276 | void bad_compound_bitand_1(int i) { |
277 | atom &= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
278 | } |
279 | |
280 | void bad_compound_bitand_2(int *i) { |
281 | *i &= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
282 | } |
283 | |
284 | void bad_compound_bitxor_1(int i) { |
285 | atom ^= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
286 | } |
287 | |
288 | void bad_compound_bitxor_2(int *i) { |
289 | *i ^= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
290 | } |
291 | |
292 | void bad_compound_bitor_1(int i) { |
293 | atom |= i; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
294 | } |
295 | |
296 | void bad_compound_bitor_2(int *i) { |
297 | *i |= atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
298 | } |
299 | |
300 | int bad_comma(int i) { |
301 | return (void)i, atom; // expected-warning {{implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary}} |
302 | } |
303 | |
304 | void good_c11_atomic_init(int i) { __c11_atomic_init(&atom, i); } |
305 | void good_c11_atomic_thread_fence(void) { __c11_atomic_thread_fence(__ATOMIC_RELAXED); } |
306 | void good_c11_atomic_signal_fence(void) { __c11_atomic_signal_fence(__ATOMIC_RELAXED); } |
307 | void good_c11_atomic_is_lock_free(void) { __c11_atomic_is_lock_free(sizeof(int)); } |
308 | void good_c11_atomic_store(int i) { __c11_atomic_store(&atom, i, __ATOMIC_RELAXED); } |
309 | int good_c11_atomic_load(void) { return __c11_atomic_load(&atom, __ATOMIC_RELAXED); } |
310 | int good_c11_atomic_exchange(int i) { return __c11_atomic_exchange(&atom, i, __ATOMIC_RELAXED); } |
311 | int good_c11_atomic_compare_exchange_strong(int *e, int i) { return __c11_atomic_compare_exchange_strong(&atom, e, i, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } |
312 | int good_c11_atomic_compare_exchange_weak(int *e, int i) { return __c11_atomic_compare_exchange_weak(&atom, e, i, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } |
313 | int good_c11_atomic_fetch_add(int i) { return __c11_atomic_fetch_add(&atom, i, __ATOMIC_RELAXED); } |
314 | int good_c11_atomic_fetch_sub(int i) { return __c11_atomic_fetch_sub(&atom, i, __ATOMIC_RELAXED); } |
315 | int good_c11_atomic_fetch_and(int i) { return __c11_atomic_fetch_and(&atom, i, __ATOMIC_RELAXED); } |
316 | int good_c11_atomic_fetch_or(int i) { return __c11_atomic_fetch_or(&atom, i, __ATOMIC_RELAXED); } |
317 | int good_c11_atomic_fetch_xor(int i) { return __c11_atomic_fetch_xor(&atom, i, __ATOMIC_RELAXED); } |
318 | |
319 | void good_cast_to_void(void) { (void)atom; } |
320 | _Atomic(int) * good_address_of(void) { return &atom; } |
321 | int good_sizeof(void) { return sizeof(atom); } |
322 | _Atomic(int) * good_pointer_arith(_Atomic(int) * p) { return p + 10; } |
323 | _Bool good_pointer_to_bool(_Atomic(int) * p) { return p; } |
324 | void good_no_init(void) { _Atomic(int) no_init; } |
325 | void good_init(void) { _Atomic(int) init = 42; } |
326 | |