1 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
2
foo()3 int foo() {
4 L1:
5 foo();
6 #pragma omp atomic
7 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
8 // expected-note@+1 {{expected an expression statement}}
9 {
10 foo();
11 goto L1; // expected-error {{use of undeclared label 'L1'}}
12 }
13 goto L2; // expected-error {{use of undeclared label 'L2'}}
14 #pragma omp atomic
15 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
16 // expected-note@+1 {{expected an expression statement}}
17 {
18 foo();
19 L2:
20 foo();
21 }
22
23 return 0;
24 }
25
26 struct S {
27 int a;
operator =S28 S &operator=(int v) {
29 a = v;
30 return *this;
31 }
operator +=S32 S &operator+=(const S &s) {
33 a += s.a;
34 return *this;
35 }
36 };
37
38 template <class T>
read()39 T read() {
40 T a = T(), b = T();
41 // Test for atomic read
42 #pragma omp atomic read
43 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
44 // expected-note@+1 {{expected an expression statement}}
45 ;
46 #pragma omp atomic read
47 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
48 // expected-note@+1 {{expected built-in assignment operator}}
49 foo();
50 #pragma omp atomic read
51 // expected-error@+2 2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
52 // expected-note@+1 2 {{expected built-in assignment operator}}
53 a += b;
54 #pragma omp atomic read
55 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
56 // expected-note@+1 {{expected lvalue expression}}
57 a = 0;
58 #pragma omp atomic read
59 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
60 // expected-note@+1 {{expected built-in assignment operator}}
61 a = b;
62 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
63 #pragma omp atomic read read
64 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
65 // expected-note@+1 {{expected built-in assignment operator}}
66 a = b;
67
68 return a;
69 }
70
read()71 int read() {
72 int a = 0, b = 0;
73 // Test for atomic read
74 #pragma omp atomic read
75 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
76 // expected-note@+1 {{expected an expression statement}}
77 ;
78 #pragma omp atomic read
79 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
80 // expected-note@+1 {{expected built-in assignment operator}}
81 foo();
82 #pragma omp atomic read
83 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
84 // expected-note@+1 {{expected built-in assignment operator}}
85 a += b;
86 #pragma omp atomic read
87 // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
88 // expected-note@+1 {{expected lvalue expression}}
89 a = 0;
90 #pragma omp atomic read
91 a = b;
92 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
93 #pragma omp atomic read read
94 a = b;
95
96 // expected-note@+2 {{in instantiation of function template specialization 'read<S>' requested here}}
97 // expected-note@+1 {{in instantiation of function template specialization 'read<int>' requested here}}
98 return read<int>() + read<S>().a;
99 }
100
101 template <class T>
write()102 T write() {
103 T a, b = 0;
104 // Test for atomic write
105 #pragma omp atomic write
106 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
107 // expected-note@+1 {{expected an expression statement}}
108 ;
109 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
110 #pragma omp atomic write write
111 a = b;
112 #pragma omp atomic write
113 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
114 // expected-note@+1 {{expected built-in assignment operator}}
115 foo();
116 #pragma omp atomic write
117 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
118 // expected-note@+1 {{expected built-in assignment operator}}
119 a += b;
120 #pragma omp atomic write
121 a = 0;
122 #pragma omp atomic write
123 a = b;
124
125 return T();
126 }
127
write()128 int write() {
129 int a, b = 0;
130 // Test for atomic write
131 #pragma omp atomic write
132 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
133 // expected-note@+1 {{expected an expression statement}}
134 ;
135 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
136 #pragma omp atomic write write
137 a = b;
138 #pragma omp atomic write
139 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
140 // expected-note@+1 {{expected built-in assignment operator}}
141 foo();
142 #pragma omp atomic write
143 // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
144 // expected-note@+1 {{expected built-in assignment operator}}
145 a += b;
146 #pragma omp atomic write
147 a = 0;
148 #pragma omp atomic write
149 a = foo();
150
151 // expected-note@+1 {{in instantiation of function template specialization 'write<int>' requested here}}
152 return write<int>();
153 }
154
155 template <class T>
update()156 T update() {
157 T a = 0, b = 0, c = 0;
158 // Test for atomic update
159 #pragma omp atomic update
160 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
161 // expected-note@+1 {{expected an expression statement}}
162 ;
163 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
164 #pragma omp atomic update update
165 a += b;
166 #pragma omp atomic
167 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
168 // expected-note@+1 {{expected built-in binary operator}}
169 a = b;
170 #pragma omp atomic update
171 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
172 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
173 a = b || a;
174 #pragma omp atomic update
175 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
176 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
177 a = a && b;
178 #pragma omp atomic update
179 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
180 // expected-note@+1 {{expected in right hand side of expression}}
181 a = float(a) + b;
182 #pragma omp atomic
183 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
184 // expected-note@+1 {{expected in right hand side of expression}}
185 a = 2 * b;
186 #pragma omp atomic
187 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
188 // expected-note@+1 {{expected in right hand side of expression}}
189 a = b + *&a;
190 #pragma omp atomic
191 *&a = b * *&a;
192 #pragma omp atomic update
193 a++;
194 #pragma omp atomic
195 ++a;
196 #pragma omp atomic update
197 a--;
198 #pragma omp atomic
199 --a;
200 #pragma omp atomic update
201 a += b;
202 #pragma omp atomic
203 a %= b;
204 #pragma omp atomic update
205 a *= b;
206 #pragma omp atomic
207 a -= b;
208 #pragma omp atomic update
209 a /= b;
210 #pragma omp atomic
211 a &= b;
212 #pragma omp atomic update
213 a ^= b;
214 #pragma omp atomic
215 a |= b;
216 #pragma omp atomic update
217 a <<= b;
218 #pragma omp atomic
219 a >>= b;
220 #pragma omp atomic update
221 a = b + a;
222 #pragma omp atomic
223 a = a * b;
224 #pragma omp atomic update
225 a = b - a;
226 #pragma omp atomic
227 a = a / b;
228 #pragma omp atomic update
229 a = b & a;
230 #pragma omp atomic
231 a = a ^ b;
232 #pragma omp atomic update
233 a = b | a;
234 #pragma omp atomic
235 a = a << b;
236 #pragma omp atomic
237 a = b >> a;
238
239 #pragma omp atomic
240 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
241 // expected-note@+1 {{expected an expression statement}}
242 ;
243
244 return T();
245 }
246
update()247 int update() {
248 int a, b = 0;
249 // Test for atomic update
250 #pragma omp atomic update
251 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
252 // expected-note@+1 {{expected an expression statement}}
253 ;
254 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
255 #pragma omp atomic update update
256 a += b;
257 #pragma omp atomic
258 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
259 // expected-note@+1 {{expected built-in binary operator}}
260 a = b;
261 #pragma omp atomic update
262 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
263 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
264 a = b || a;
265 #pragma omp atomic update
266 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
267 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
268 a = a && b;
269 #pragma omp atomic update
270 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
271 // expected-note@+1 {{expected in right hand side of expression}}
272 a = float(a) + b;
273 #pragma omp atomic
274 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
275 // expected-note@+1 {{expected in right hand side of expression}}
276 a = 2 * b;
277 #pragma omp atomic
278 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
279 // expected-note@+1 {{expected in right hand side of expression}}
280 a = b + *&a;
281 #pragma omp atomic update
282 a++;
283 #pragma omp atomic
284 ++a;
285 #pragma omp atomic update
286 a--;
287 #pragma omp atomic
288 --a;
289 #pragma omp atomic update
290 a += b;
291 #pragma omp atomic
292 a %= b;
293 #pragma omp atomic update
294 a *= b;
295 #pragma omp atomic
296 a -= b;
297 #pragma omp atomic update
298 a /= b;
299 #pragma omp atomic
300 a &= b;
301 #pragma omp atomic update
302 a ^= b;
303 #pragma omp atomic
304 a |= b;
305 #pragma omp atomic update
306 a <<= b;
307 #pragma omp atomic
308 a >>= b;
309 #pragma omp atomic update
310 a = b + a;
311 #pragma omp atomic
312 a = a * b;
313 #pragma omp atomic update
314 a = b - a;
315 #pragma omp atomic
316 a = a / b;
317 #pragma omp atomic update
318 a = b & a;
319 #pragma omp atomic
320 a = a ^ b;
321 #pragma omp atomic update
322 a = b | a;
323 #pragma omp atomic
324 a = a << b;
325 #pragma omp atomic
326 a = b >> a;
327 #pragma omp atomic
328 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
329 // expected-note@+1 {{expected an expression statement}}
330 ;
331
332 return update<int>();
333 }
334
335 template <class T>
capture()336 T capture() {
337 T a = 0, b = 0, c = 0;
338 // Test for atomic capture
339 #pragma omp atomic capture
340 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
341 // expected-note@+1 {{expected compound statement}}
342 ;
343 #pragma omp atomic capture
344 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
345 // expected-note@+1 {{expected assignment expression}}
346 foo();
347 #pragma omp atomic capture
348 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
349 // expected-note@+1 {{expected built-in binary or unary operator}}
350 a = b;
351 #pragma omp atomic capture
352 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
353 // expected-note@+1 {{expected assignment expression}}
354 a = b || a;
355 #pragma omp atomic capture
356 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
357 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
358 b = a = a && b;
359 #pragma omp atomic capture
360 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
361 // expected-note@+1 {{expected assignment expression}}
362 a = (float)a + b;
363 #pragma omp atomic capture
364 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
365 // expected-note@+1 {{expected assignment expression}}
366 a = 2 * b;
367 #pragma omp atomic capture
368 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
369 // expected-note@+1 {{expected assignment expression}}
370 a = b + *&a;
371 #pragma omp atomic capture
372 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
373 // expected-note@+1 {{expected exactly two expression statements}}
374 { a = b; }
375 #pragma omp atomic capture
376 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
377 // expected-note@+1 {{expected exactly two expression statements}}
378 {}
379 #pragma omp atomic capture
380 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
381 // expected-note@+1 {{expected in right hand side of the first expression}}
382 {a = b;a = b;}
383 #pragma omp atomic capture
384 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
385 // expected-note@+1 {{expected in right hand side of the first expression}}
386 {a = b; a = b || a;}
387 #pragma omp atomic capture
388 {b = a; a = a && b;}
389 #pragma omp atomic capture
390 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
391 // expected-note@+1 {{expected in right hand side of expression}}
392 b = a = (float)a + b;
393 #pragma omp atomic capture
394 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
395 // expected-note@+1 {{expected in right hand side of expression}}
396 b = a = 2 * b;
397 #pragma omp atomic capture
398 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
399 // expected-note@+1 {{expected in right hand side of expression}}
400 b = a = b + *&a;
401 #pragma omp atomic capture
402 c = *&a = *&a + 2;
403 #pragma omp atomic capture
404 c = a++;
405 #pragma omp atomic capture
406 c = ++a;
407 #pragma omp atomic capture
408 c = a--;
409 #pragma omp atomic capture
410 c = --a;
411 #pragma omp atomic capture
412 c = a += b;
413 #pragma omp atomic capture
414 c = a %= b;
415 #pragma omp atomic capture
416 c = a *= b;
417 #pragma omp atomic capture
418 c = a -= b;
419 #pragma omp atomic capture
420 c = a /= b;
421 #pragma omp atomic capture
422 c = a &= b;
423 #pragma omp atomic capture
424 c = a ^= b;
425 #pragma omp atomic capture
426 c = a |= b;
427 #pragma omp atomic capture
428 c = a <<= b;
429 #pragma omp atomic capture
430 c = a >>= b;
431 #pragma omp atomic capture
432 c = a = b + a;
433 #pragma omp atomic capture
434 c = a = a * b;
435 #pragma omp atomic capture
436 c = a = b - a;
437 #pragma omp atomic capture
438 c = a = a / b;
439 #pragma omp atomic capture
440 c = a = b & a;
441 #pragma omp atomic capture
442 c = a = a ^ b;
443 #pragma omp atomic capture
444 c = a = b | a;
445 #pragma omp atomic capture
446 c = a = a << b;
447 #pragma omp atomic capture
448 c = a = b >> a;
449 #pragma omp atomic capture
450 { c = *&a; *&a = *&a + 2;}
451 #pragma omp atomic capture
452 { *&a = *&a + 2; c = *&a;}
453 #pragma omp atomic capture
454 {c = a; a++;}
455 #pragma omp atomic capture
456 {++a;c = a;}
457 #pragma omp atomic capture
458 {c = a;a--;}
459 #pragma omp atomic capture
460 {--a;c = a;}
461 #pragma omp atomic capture
462 {c = a; a += b;}
463 #pragma omp atomic capture
464 {a %= b; c = a;}
465 #pragma omp atomic capture
466 {c = a; a *= b;}
467 #pragma omp atomic capture
468 {a -= b;c = a;}
469 #pragma omp atomic capture
470 {c = a; a /= b;}
471 #pragma omp atomic capture
472 {a &= b; c = a;}
473 #pragma omp atomic capture
474 {c = a; a ^= b;}
475 #pragma omp atomic capture
476 {a |= b; c = a;}
477 #pragma omp atomic capture
478 {c = a; a <<= b;}
479 #pragma omp atomic capture
480 {a >>= b; c = a;}
481 #pragma omp atomic capture
482 {c = a; a = b + a;}
483 #pragma omp atomic capture
484 {a = a * b; c = a;}
485 #pragma omp atomic capture
486 {c = a; a = b - a;}
487 #pragma omp atomic capture
488 {a = a / b; c = a;}
489 #pragma omp atomic capture
490 {c = a; a = b & a;}
491 #pragma omp atomic capture
492 {a = a ^ b; c = a;}
493 #pragma omp atomic capture
494 {c = a; a = b | a;}
495 #pragma omp atomic capture
496 {a = a << b; c = a;}
497 #pragma omp atomic capture
498 {c = a; a = b >> a;}
499 #pragma omp atomic capture
500 {c = a; a = foo();}
501 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
502 #pragma omp atomic capture capture
503 b = a /= b;
504
505 return T();
506 }
507
capture()508 int capture() {
509 int a = 0, b = 0, c = 0;
510 // Test for atomic capture
511 #pragma omp atomic capture
512 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
513 // expected-note@+1 {{expected compound statement}}
514 ;
515 #pragma omp atomic capture
516 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
517 // expected-note@+1 {{expected assignment expression}}
518 foo();
519 #pragma omp atomic capture
520 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
521 // expected-note@+1 {{expected built-in binary or unary operator}}
522 a = b;
523 #pragma omp atomic capture
524 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
525 // expected-note@+1 {{expected assignment expression}}
526 a = b || a;
527 #pragma omp atomic capture
528 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
529 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
530 b = a = a && b;
531 #pragma omp atomic capture
532 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
533 // expected-note@+1 {{expected assignment expression}}
534 a = (float)a + b;
535 #pragma omp atomic capture
536 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
537 // expected-note@+1 {{expected assignment expression}}
538 a = 2 * b;
539 #pragma omp atomic capture
540 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
541 // expected-note@+1 {{expected assignment expression}}
542 a = b + *&a;
543 #pragma omp atomic capture
544 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
545 // expected-note@+1 {{expected exactly two expression statements}}
546 { a = b; }
547 #pragma omp atomic capture
548 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
549 // expected-note@+1 {{expected exactly two expression statements}}
550 {}
551 #pragma omp atomic capture
552 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
553 // expected-note@+1 {{expected in right hand side of the first expression}}
554 {a = b;a = b;}
555 #pragma omp atomic capture
556 // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
557 // expected-note@+1 {{expected in right hand side of the first expression}}
558 {a = b; a = b || a;}
559 #pragma omp atomic capture
560 {b = a; a = a && b;}
561 #pragma omp atomic capture
562 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
563 // expected-note@+1 {{expected in right hand side of expression}}
564 b = a = (float)a + b;
565 #pragma omp atomic capture
566 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
567 // expected-note@+1 {{expected in right hand side of expression}}
568 b = a = 2 * b;
569 #pragma omp atomic capture
570 // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
571 // expected-note@+1 {{expected in right hand side of expression}}
572 b = a = b + *&a;
573 #pragma omp atomic capture
574 c = *&a = *&a + 2;
575 #pragma omp atomic capture
576 c = a++;
577 #pragma omp atomic capture
578 c = ++a;
579 #pragma omp atomic capture
580 c = a--;
581 #pragma omp atomic capture
582 c = --a;
583 #pragma omp atomic capture
584 c = a += b;
585 #pragma omp atomic capture
586 c = a %= b;
587 #pragma omp atomic capture
588 c = a *= b;
589 #pragma omp atomic capture
590 c = a -= b;
591 #pragma omp atomic capture
592 c = a /= b;
593 #pragma omp atomic capture
594 c = a &= b;
595 #pragma omp atomic capture
596 c = a ^= b;
597 #pragma omp atomic capture
598 c = a |= b;
599 #pragma omp atomic capture
600 c = a <<= b;
601 #pragma omp atomic capture
602 c = a >>= b;
603 #pragma omp atomic capture
604 c = a = b + a;
605 #pragma omp atomic capture
606 c = a = a * b;
607 #pragma omp atomic capture
608 c = a = b - a;
609 #pragma omp atomic capture
610 c = a = a / b;
611 #pragma omp atomic capture
612 c = a = b & a;
613 #pragma omp atomic capture
614 c = a = a ^ b;
615 #pragma omp atomic capture
616 c = a = b | a;
617 #pragma omp atomic capture
618 c = a = a << b;
619 #pragma omp atomic capture
620 c = a = b >> a;
621 #pragma omp atomic capture
622 { c = *&a; *&a = *&a + 2;}
623 #pragma omp atomic capture
624 { *&a = *&a + 2; c = *&a;}
625 #pragma omp atomic capture
626 {c = a; a++;}
627 #pragma omp atomic capture
628 {++a;c = a;}
629 #pragma omp atomic capture
630 {c = a;a--;}
631 #pragma omp atomic capture
632 {--a;c = a;}
633 #pragma omp atomic capture
634 {c = a; a += b;}
635 #pragma omp atomic capture
636 {a %= b; c = a;}
637 #pragma omp atomic capture
638 {c = a; a *= b;}
639 #pragma omp atomic capture
640 {a -= b;c = a;}
641 #pragma omp atomic capture
642 {c = a; a /= b;}
643 #pragma omp atomic capture
644 {a &= b; c = a;}
645 #pragma omp atomic capture
646 {c = a; a ^= b;}
647 #pragma omp atomic capture
648 {a |= b; c = a;}
649 #pragma omp atomic capture
650 {c = a; a <<= b;}
651 #pragma omp atomic capture
652 {a >>= b; c = a;}
653 #pragma omp atomic capture
654 {c = a; a = b + a;}
655 #pragma omp atomic capture
656 {a = a * b; c = a;}
657 #pragma omp atomic capture
658 {c = a; a = b - a;}
659 #pragma omp atomic capture
660 {a = a / b; c = a;}
661 #pragma omp atomic capture
662 {c = a; a = b & a;}
663 #pragma omp atomic capture
664 {a = a ^ b; c = a;}
665 #pragma omp atomic capture
666 {c = a; a = b | a;}
667 #pragma omp atomic capture
668 {a = a << b; c = a;}
669 #pragma omp atomic capture
670 {c = a; a = b >> a;}
671 #pragma omp atomic capture
672 {c = a; a = foo();}
673 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
674 #pragma omp atomic capture capture
675 b = a /= b;
676
677 // expected-note@+1 {{in instantiation of function template specialization 'capture<int>' requested here}}
678 return capture<int>();
679 }
680
681 template <class T>
seq_cst()682 T seq_cst() {
683 T a, b = 0;
684 // Test for atomic seq_cst
685 #pragma omp atomic seq_cst
686 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
687 // expected-note@+1 {{expected an expression statement}}
688 ;
689 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
690 #pragma omp atomic seq_cst seq_cst
691 a += b;
692
693 #pragma omp atomic update seq_cst
694 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
695 // expected-note@+1 {{expected an expression statement}}
696 ;
697
698 return T();
699 }
700
seq_cst()701 int seq_cst() {
702 int a, b = 0;
703 // Test for atomic seq_cst
704 #pragma omp atomic seq_cst
705 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
706 // expected-note@+1 {{expected an expression statement}}
707 ;
708 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
709 #pragma omp atomic seq_cst seq_cst
710 a += b;
711
712 #pragma omp atomic update seq_cst
713 // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
714 // expected-note@+1 {{expected an expression statement}}
715 ;
716
717 return seq_cst<int>();
718 }
719
720 template <class T>
mixed()721 T mixed() {
722 T a, b = T();
723 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
724 // expected-note@+1 2 {{'read' clause used here}}
725 #pragma omp atomic read write
726 a = b;
727 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
728 // expected-note@+1 2 {{'write' clause used here}}
729 #pragma omp atomic write read
730 a = b;
731 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
732 // expected-note@+1 2 {{'update' clause used here}}
733 #pragma omp atomic update read
734 a += b;
735 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
736 // expected-note@+1 2 {{'capture' clause used here}}
737 #pragma omp atomic capture read
738 a = ++b;
739 return T();
740 }
741
mixed()742 int mixed() {
743 int a, b = 0;
744 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
745 // expected-note@+1 {{'read' clause used here}}
746 #pragma omp atomic read write
747 a = b;
748 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
749 // expected-note@+1 {{'write' clause used here}}
750 #pragma omp atomic write read
751 a = b;
752 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
753 // expected-note@+1 {{'write' clause used here}}
754 #pragma omp atomic write update
755 a = b;
756 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
757 // expected-note@+1 {{'write' clause used here}}
758 #pragma omp atomic write capture
759 a = b;
760 // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}}
761 return mixed<int>();
762 }
763
764