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 
bad_pre_inc(void)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 
bad_pre_dec(void)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 
bad_post_inc(void)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 
bad_post_dec(void)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 
bad_call(void)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 
bad_unary_plus(void)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 
bad_unary_minus(void)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 
bad_unary_logical_not(void)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 
bad_unary_bitwise_not(void)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 
bad_explicit_cast(void)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 
bad_implicit_cast(void)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 
bad_mul_1(int i)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 
bad_mul_2(int i)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 
bad_div_1(int i)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 
bad_div_2(int i)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 
bad_mod_1(int i)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 
bad_mod_2(int i)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 
bad_add_1(int i)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 
bad_add_2(int i)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 
bad_sub_1(int i)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 
bad_sub_2(int i)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 
bad_shl_1(int i)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 
bad_shl_2(int i)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 
bad_shr_1(int i)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 
bad_shr_2(int i)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 
bad_lt_1(int i)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 
bad_lt_2(int i)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 
bad_le_1(int i)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 
bad_le_2(int i)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 
bad_gt_1(int i)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 
bad_gt_2(int i)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 
bad_ge_1(int i)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 
bad_ge_2(int i)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 
bad_eq_1(int i)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 
bad_eq_2(int i)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 
bad_ne_1(int i)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 
bad_ne_2(int i)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 
bad_bitand_1(int i)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 
bad_bitand_2(int i)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 
bad_bitxor_1(int i)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 
bad_bitxor_2(int i)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 
bad_bitor_1(int i)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 
bad_bitor_2(int i)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 
bad_and_1(int i)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 
bad_and_2(int i)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 
bad_or_1(int i)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 
bad_or_2(int i)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 }
bad_ternary_1(int i,int j)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 
bad_ternary_2(int i,int j)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 
bad_ternary_3(int i,int j)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 
bad_assign_1(int i)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 
bad_assign_2(int * i)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 
bad_assign_3()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 
bad_compound_add_1(int i)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 
bad_compound_add_2(int * i)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 
bad_compound_sub_1(int i)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 
bad_compound_sub_2(int * i)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 
bad_compound_mul_1(int i)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 
bad_compound_mul_2(int * i)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 
bad_compound_div_1(int i)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 
bad_compound_div_2(int * i)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 
bad_compound_mod_1(int i)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 
bad_compound_mod_2(int * i)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 
bad_compound_shl_1(int i)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 
bad_compound_shl_2(int * i)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 
bad_compound_shr_1(int i)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 
bad_compound_shr_2(int * i)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 
bad_compound_bitand_1(int i)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 
bad_compound_bitand_2(int * i)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 
bad_compound_bitxor_1(int i)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 
bad_compound_bitxor_2(int * i)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 
bad_compound_bitor_1(int i)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 
bad_compound_bitor_2(int * i)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 
bad_comma(int i)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 
good_c11_atomic_init(int i)304 void good_c11_atomic_init(int i) { __c11_atomic_init(&atom, i); }
good_c11_atomic_thread_fence(void)305 void good_c11_atomic_thread_fence(void) { __c11_atomic_thread_fence(__ATOMIC_RELAXED); }
good_c11_atomic_signal_fence(void)306 void good_c11_atomic_signal_fence(void) { __c11_atomic_signal_fence(__ATOMIC_RELAXED); }
good_c11_atomic_is_lock_free(void)307 void good_c11_atomic_is_lock_free(void) { __c11_atomic_is_lock_free(sizeof(int)); }
good_c11_atomic_store(int i)308 void good_c11_atomic_store(int i) { __c11_atomic_store(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_load(void)309 int good_c11_atomic_load(void) { return __c11_atomic_load(&atom, __ATOMIC_RELAXED); }
good_c11_atomic_exchange(int i)310 int good_c11_atomic_exchange(int i) { return __c11_atomic_exchange(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_compare_exchange_strong(int * e,int i)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); }
good_c11_atomic_compare_exchange_weak(int * e,int i)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); }
good_c11_atomic_fetch_add(int i)313 int good_c11_atomic_fetch_add(int i) { return __c11_atomic_fetch_add(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_fetch_sub(int i)314 int good_c11_atomic_fetch_sub(int i) { return __c11_atomic_fetch_sub(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_fetch_and(int i)315 int good_c11_atomic_fetch_and(int i) { return __c11_atomic_fetch_and(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_fetch_or(int i)316 int good_c11_atomic_fetch_or(int i) { return __c11_atomic_fetch_or(&atom, i, __ATOMIC_RELAXED); }
good_c11_atomic_fetch_xor(int i)317 int good_c11_atomic_fetch_xor(int i) { return __c11_atomic_fetch_xor(&atom, i, __ATOMIC_RELAXED); }
318 
good_cast_to_void(void)319 void good_cast_to_void(void) { (void)atom; }
_Atomic(int)320 _Atomic(int) * good_address_of(void) { return &atom; }
good_sizeof(void)321 int good_sizeof(void) { return sizeof(atom); }
_Atomic(int)322 _Atomic(int) * good_pointer_arith(_Atomic(int) * p) { return p + 10; }
good_pointer_to_bool(_Atomic (int)* p)323 _Bool good_pointer_to_bool(_Atomic(int) * p) { return p; }
good_no_init(void)324 void good_no_init(void) { _Atomic(int) no_init; }
good_init(void)325 void good_init(void) { _Atomic(int) init = 42; }
326