1 // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 150 %s -Wuninitialized
2 // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -ferror-limit 150 %s -Wuninitialized
3 
4 // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 150 %s -Wuninitialized
5 // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -ferror-limit 150 %s -Wuninitialized
6 
foo()7 int foo() {
8 L1:
9   foo();
10 #pragma omp atomic
11   // 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 lvalue expression with scalar type}}
12   // expected-note@+1 {{expected an expression statement}}
13   {
14     foo();
15     goto L1;
16   }
17   goto L2;
18 #pragma omp atomic
19   // 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 lvalue expression with scalar type}}
20   // expected-note@+1 {{expected an expression statement}}
21   {
22     foo();
23   L2:
24     foo();
25   }
26 
27   return 0;
28 }
29 
30 struct S {
31   int a;
operator =S32   S &operator=(int v) {
33     a = v;
34     return *this;
35   }
operator +=S36   S &operator+=(const S &s) {
37     a += s.a;
38     return *this;
39   }
40 };
41 
42 template <class T>
read()43 T read() {
44   T a = T(), b = T();
45 // Test for atomic read
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 an expression statement}}
49   ;
50 #pragma omp atomic read
51   // 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}}
52   // expected-note@+1 {{expected built-in assignment operator}}
53   foo();
54 #pragma omp atomic read
55   // 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}}
56   // expected-note@+1 2 {{expected built-in assignment operator}}
57   a += b;
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 lvalue expression}}
61   a = 0;
62 #pragma omp atomic read
63   // 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}}
64   // expected-note@+1 {{expected built-in assignment operator}}
65   a = b;
66   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
67 #pragma omp atomic read read
68   // 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}}
69   // expected-note@+1 {{expected built-in assignment operator}}
70   a = b;
71 
72   return a;
73 }
74 
read()75 int read() {
76   int a = 0, b = 0;
77 // Test for atomic read
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 an expression statement}}
81   ;
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   foo();
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 built-in assignment operator}}
89   a += b;
90 #pragma omp atomic read
91   // 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}}
92   // expected-note@+1 {{expected lvalue expression}}
93   a = 0;
94 #pragma omp atomic read
95   a = b;
96   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
97 #pragma omp atomic read read
98   a = b;
99 
100   // expected-note@+2 {{in instantiation of function template specialization 'read<S>' requested here}}
101   // expected-note@+1 {{in instantiation of function template specialization 'read<int>' requested here}}
102   return read<int>() + read<S>().a;
103 }
104 
105 template <class T>
write()106 T write() {
107   T a, b = 0;
108 // Test for atomic write
109 #pragma omp atomic write
110   // 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}}
111   // expected-note@+1 {{expected an expression statement}}
112   ;
113 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
114 #pragma omp atomic write write
115   a = b;
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   foo();
120 #pragma omp atomic write
121   // 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}}
122   // expected-note@+1 {{expected built-in assignment operator}}
123   a += b;
124 #pragma omp atomic write
125   a = 0;
126 #pragma omp atomic write
127   a = b;
128 
129   return T();
130 }
131 
write()132 int write() {
133   int a, b = 0;
134 // Test for atomic write
135 #pragma omp atomic write
136   // 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}}
137   // expected-note@+1 {{expected an expression statement}}
138   ;
139 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
140 #pragma omp atomic write write
141   a = b;
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   foo();
146 #pragma omp atomic write
147   // 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}}
148   // expected-note@+1 {{expected built-in assignment operator}}
149   a += b;
150 #pragma omp atomic write
151   a = 0;
152 #pragma omp atomic write
153   a = foo();
154 
155   // expected-note@+1 {{in instantiation of function template specialization 'write<int>' requested here}}
156   return write<int>();
157 }
158 
159 template <class T>
update()160 T update() {
161   T a = 0, b = 0, c = 0;
162 // Test for atomic update
163 #pragma omp atomic update
164   // 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 lvalue expression with scalar type}}
165   // expected-note@+1 {{expected an expression statement}}
166   ;
167 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
168 #pragma omp atomic update update
169   a += b;
170 #pragma omp atomic
171   // 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 lvalue expression with scalar type}}
172   // expected-note@+1 {{expected built-in binary operator}}
173   a = b;
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 lvalue expression with scalar type}}
176   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
177   a = b || a;
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 lvalue expression with scalar type}}
180   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
181   a = a && b;
182 #pragma omp atomic update
183   // 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 lvalue expression with scalar type}}
184   // expected-note@+1 {{expected in right hand side of expression}}
185   a = float(a) + 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 lvalue expression with scalar type}}
188   // expected-note@+1 {{expected in right hand side of expression}}
189   a = 2 * b;
190 #pragma omp atomic
191   // 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 lvalue expression with scalar type}}
192   // expected-note@+1 {{expected in right hand side of expression}}
193   a = b + *&a;
194 #pragma omp atomic
195   *&a = b * *&a;
196 #pragma omp atomic update
197   a++;
198 #pragma omp atomic
199   ++a;
200 #pragma omp atomic update
201   a--;
202 #pragma omp atomic
203   --a;
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;
222 #pragma omp atomic
223   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 update
237   a = b | a;
238 #pragma omp atomic
239   a = a << b;
240 #pragma omp atomic
241   a = b >> a;
242 
243 #pragma omp atomic
244   // 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 lvalue expression with scalar type}}
245   // expected-note@+1 {{expected an expression statement}}
246   ;
247 
248   return T();
249 }
250 
update()251 int update() {
252   int a, b = 0;
253 // Test for atomic update
254 #pragma omp atomic update
255   // 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 lvalue expression with scalar type}}
256   // expected-note@+1 {{expected an expression statement}}
257   ;
258 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
259 #pragma omp atomic update update
260   a += b;
261 #pragma omp atomic
262   // 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 lvalue expression with scalar type}}
263   // expected-note@+1 {{expected built-in binary operator}}
264   a = b;
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 lvalue expression with scalar type}}
267   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
268   a = b || a;
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 lvalue expression with scalar type}}
271   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
272   a = a && b;
273 #pragma omp atomic update
274   // 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 lvalue expression with scalar type}}
275   // expected-note@+1 {{expected in right hand side of expression}}
276   a = float(a) + 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 lvalue expression with scalar type}}
279   // expected-note@+1 {{expected in right hand side of expression}}
280   a = 2 * b;
281 #pragma omp atomic
282   // 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 lvalue expression with scalar type}}
283   // expected-note@+1 {{expected in right hand side of expression}}
284   a = b + *&a;
285 #pragma omp atomic update
286   a++;
287 #pragma omp atomic
288   ++a;
289 #pragma omp atomic update
290   a--;
291 #pragma omp atomic
292   --a;
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;
311 #pragma omp atomic
312   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 update
326   a = b | a;
327 #pragma omp atomic
328   a = a << b;
329 #pragma omp atomic
330   a = b >> a;
331 #pragma omp atomic
332   // 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 lvalue expression with scalar type}}
333   // expected-note@+1 {{expected an expression statement}}
334   ;
335 
336   return update<int>();
337 }
338 
339 template <class T>
capture()340 T capture() {
341   T a = 0, b = 0, c = 0;
342 // Test for atomic capture
343 #pragma omp atomic capture
344   // 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 lvalue expression with scalar type}}
345   // expected-note@+1 {{expected compound statement}}
346   ;
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 lvalue expressions with scalar type}}
349   // expected-note@+1 {{expected assignment expression}}
350   foo();
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 lvalue expressions with scalar type}}
353   // expected-note@+1 {{expected built-in binary or unary operator}}
354   a = b;
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 lvalue expressions with scalar type}}
357   // expected-note@+1 {{expected assignment expression}}
358   a = b || a;
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 lvalue expressions with scalar type}}
361   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
362   b = a = 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 lvalue expressions with scalar type}}
365   // expected-note@+1 {{expected assignment expression}}
366   a = (float)a + 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 lvalue expressions with scalar type}}
369   // expected-note@+1 {{expected assignment expression}}
370   a = 2 * b;
371 #pragma omp atomic capture
372   // 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 lvalue expressions with scalar type}}
373   // expected-note@+1 {{expected assignment expression}}
374   a = b + *&a;
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 lvalue expression with scalar type}}
377   // expected-note@+1 {{expected exactly two expression statements}}
378   { a = b; }
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 lvalue expression with scalar type}}
381   // expected-note@+1 {{expected exactly two expression statements}}
382   {}
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 lvalue expression with scalar type}}
385   // expected-note@+1 {{expected in right hand side of the first expression}}
386   {a = b;a = b;}
387 #pragma omp atomic capture
388   // 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 lvalue expression with scalar type}}
389   // expected-note@+1 {{expected in right hand side of the first expression}}
390   {a = b; a = b || a;}
391 #pragma omp atomic capture
392   {b = a; a = 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 lvalue expressions with scalar type}}
395   // expected-note@+1 {{expected in right hand side of expression}}
396   b = a = (float)a + 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 lvalue expressions with scalar type}}
399   // expected-note@+1 {{expected in right hand side of expression}}
400   b = a = 2 * b;
401 #pragma omp atomic capture
402   // 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 lvalue expressions with scalar type}}
403   // expected-note@+1 {{expected in right hand side of expression}}
404   b = a = b + *&a;
405 #pragma omp atomic capture
406   c = *&a = *&a +  2;
407 #pragma omp atomic capture
408   c = a++;
409 #pragma omp atomic capture
410   c = ++a;
411 #pragma omp atomic capture
412   c = a--;
413 #pragma omp atomic capture
414   c = --a;
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;
433 #pragma omp atomic capture
434   c = 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 << b;
451 #pragma omp atomic capture
452   c = a = b >> a;
453 #pragma omp atomic capture
454   { c = *&a; *&a = *&a +  2;}
455 #pragma omp atomic capture
456   { *&a = *&a +  2; c = *&a;}
457 #pragma omp atomic capture
458   {c = a; a++;}
459 #pragma omp atomic capture
460   {c = a; (a)++;}
461 #pragma omp atomic capture
462   {++a;c = a;}
463 #pragma omp atomic capture
464   {c = a;a--;}
465 #pragma omp atomic capture
466   {--a;c = a;}
467 #pragma omp atomic capture
468   {c = a; a += b;}
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;}
483 #pragma omp atomic capture
484   {a |= b; c = a;}
485 #pragma omp atomic capture
486   {c = a; a <<= b;}
487 #pragma omp atomic capture
488   {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   {a = a ^ b; c = a;}
501 #pragma omp atomic capture
502   {c = a; a = b | a;}
503 #pragma omp atomic capture
504   {a = a << b; c = a;}
505 #pragma omp atomic capture
506   {c = a; a = b >> a;}
507 #pragma omp atomic capture
508   {c = a; a = foo();}
509   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
510 #pragma omp atomic capture capture
511   b = a /= b;
512 
513   return T();
514 }
515 
capture()516 int capture() {
517   int a = 0, b = 0, c = 0;
518 // Test for atomic capture
519 #pragma omp atomic capture
520   // 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 lvalue expression with scalar type}}
521   // expected-note@+1 {{expected compound statement}}
522   ;
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 lvalue expressions with scalar type}}
525   // expected-note@+1 {{expected assignment expression}}
526   foo();
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 lvalue expressions with scalar type}}
529   // expected-note@+1 {{expected built-in binary or unary operator}}
530   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 lvalue expressions with scalar type}}
533   // expected-note@+1 {{expected assignment expression}}
534   a = b || a;
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 lvalue expressions with scalar type}}
537   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
538   b = a = a && 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 lvalue expressions with scalar type}}
541   // expected-note@+1 {{expected assignment expression}}
542   a = (float)a + b;
543 #pragma omp atomic capture
544   // 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 lvalue expressions with scalar type}}
545   // expected-note@+1 {{expected assignment expression}}
546   a = 2 * b;
547 #pragma omp atomic capture
548   // 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 lvalue expressions with scalar type}}
549   // expected-note@+1 {{expected assignment expression}}
550   a = b + *&a;
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 lvalue expression with scalar type}}
553   // expected-note@+1 {{expected exactly two expression statements}}
554   { 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 lvalue expression with scalar type}}
557   // expected-note@+1 {{expected exactly two expression statements}}
558   {}
559 #pragma omp atomic capture
560   // 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 lvalue expression with scalar type}}
561   // expected-note@+1 {{expected in right hand side of the first expression}}
562   {a = b;a = b;}
563 #pragma omp atomic capture
564   // 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 lvalue expression with scalar type}}
565   // expected-note@+1 {{expected in right hand side of the first expression}}
566   {a = b; a = b || a;}
567 #pragma omp atomic capture
568   {b = a; a = a && 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 lvalue expressions with scalar type}}
571   // expected-note@+1 {{expected in right hand side of expression}}
572   b = a = (float)a + b;
573 #pragma omp atomic capture
574   // 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 lvalue expressions with scalar type}}
575   // expected-note@+1 {{expected in right hand side of expression}}
576   b = a = 2 * b;
577 #pragma omp atomic capture
578   // 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 lvalue expressions with scalar type}}
579   // expected-note@+1 {{expected in right hand side of expression}}
580   b = a = b + *&a;
581 #pragma omp atomic capture
582   c = *&a = *&a +  2;
583 #pragma omp atomic capture
584   c = a++;
585 #pragma omp atomic capture
586   c = ++a;
587 #pragma omp atomic capture
588   c = a--;
589 #pragma omp atomic capture
590   c = --a;
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;
605 #pragma omp atomic capture
606   c = a |= b;
607 #pragma omp atomic capture
608   c = a <<= b;
609 #pragma omp atomic capture
610   c = 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 ^ b;
623 #pragma omp atomic capture
624   c = a = b | a;
625 #pragma omp atomic capture
626   c = a = a << b;
627 #pragma omp atomic capture
628   c = a = b >> a;
629 #pragma omp atomic capture
630   { c = *&a; *&a = *&a +  2;}
631 #pragma omp atomic capture
632   { *&a = *&a +  2; c = *&a;}
633 #pragma omp atomic capture
634   {c = a; a++;}
635 #pragma omp atomic capture
636   {++a;c = a;}
637 #pragma omp atomic capture
638   {c = a;a--;}
639 #pragma omp atomic capture
640   {--a;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;}
655 #pragma omp atomic capture
656   {a |= b; c = a;}
657 #pragma omp atomic capture
658   {c = a; a <<= b;}
659 #pragma omp atomic capture
660   {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   {a = a ^ b; c = a;}
673 #pragma omp atomic capture
674   {c = a; a = b | a;}
675 #pragma omp atomic capture
676   {a = a << b; c = a;}
677 #pragma omp atomic capture
678   {c = a; a = b >> a;}
679 #pragma omp atomic capture
680   {c = a; a = foo();}
681   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
682 #pragma omp atomic capture capture
683   b = a /= b;
684 
685   // expected-note@+1 {{in instantiation of function template specialization 'capture<int>' requested here}}
686   return capture<int>();
687 }
688 
689 template <class T>
seq_cst()690 T seq_cst() {
691   T a, b = 0;
692 // Test for atomic seq_cst
693 #pragma omp atomic seq_cst
694   // 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 lvalue expression with scalar type}}
695   // expected-note@+1 {{expected an expression statement}}
696   ;
697 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
698 #pragma omp atomic seq_cst seq_cst
699   a += b;
700 
701 #pragma omp atomic update seq_cst
702   // 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 lvalue expression with scalar type}}
703   // expected-note@+1 {{expected an expression statement}}
704   ;
705 
706   return T();
707 }
708 
seq_cst()709 int seq_cst() {
710   int a, b = 0;
711 // Test for atomic seq_cst
712 #pragma omp atomic seq_cst
713   // 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 lvalue expression with scalar type}}
714   // expected-note@+1 {{expected an expression statement}}
715   ;
716 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
717 #pragma omp atomic seq_cst seq_cst
718   a += b;
719 
720 #pragma omp atomic update seq_cst
721   // 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 lvalue expression with scalar type}}
722   // expected-note@+1 {{expected an expression statement}}
723   ;
724 
725  return seq_cst<int>();
726 }
727 
728 template <class T>
acq_rel()729 T acq_rel() {
730   T a = 0, b = 0;
731 // omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic' cannot be used with 'acq_rel' clause}} omp50-note@+1 {{'acq_rel' clause used here}}
732 #pragma omp atomic acq_rel
733   // 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 lvalue expression with scalar type}}
734   // expected-note@+1 {{expected an expression statement}}
735   ;
736 // omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error@+1 2 {{directive '#pragma omp atomic read' cannot be used with 'acq_rel' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}}
737 #pragma omp atomic read acq_rel seq_cst
738   a = b;
739 
740 // omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic update' cannot be used with 'acq_rel' clause}} omp50-note@+1 {{'acq_rel' clause used here}}
741 #pragma omp atomic update acq_rel
742   // 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 lvalue expression with scalar type}}
743   // expected-note@+1 {{expected an expression statement}}
744   ;
745 
746   return T();
747 }
748 
acq_rel()749 int acq_rel() {
750   int a = 0, b = 0;
751 // Test for atomic acq_rel
752 // omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic write' cannot be used with 'acq_rel' clause}} omp50-note@+1 {{'acq_rel' clause used here}}
753 #pragma omp atomic acq_rel write
754   // 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}}
755   // expected-note@+1 {{expected an expression statement}}
756   ;
757 // omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
758 #pragma omp atomic seq_cst acq_rel
759   a += b;
760 
761 // omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic update' cannot be used with 'acq_rel' clause}} omp50-note@+1 {{'acq_rel' clause used here}}
762 #pragma omp atomic update acq_rel
763   // 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 lvalue expression with scalar type}}
764   // expected-note@+1 {{expected an expression statement}}
765   ;
766 
767  return acq_rel<int>(); // omp50-note {{in instantiation of function template specialization 'acq_rel<int>' requested here}}
768 }
769 
770 template <class T>
acquire()771 T acquire() {
772   T a = 0, b = 0;
773 // omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic' cannot be used with 'acquire' clause}} omp50-note@+1 {{'acquire' clause used here}}
774 #pragma omp atomic acquire
775   // 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 lvalue expression with scalar type}}
776   // expected-note@+1 {{expected an expression statement}}
777   ;
778 // omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'acquire' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error@+1 2 {{directive '#pragma omp atomic' cannot be used with 'acquire' clause}} omp50-note@+1 2 {{'acquire' clause used here}}
779 #pragma omp atomic acquire seq_cst
780   a += b;
781 
782 // omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic update' cannot be used with 'acquire' clause}} omp50-note@+1 {{'acquire' clause used here}}
783 #pragma omp atomic update acquire
784   // 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 lvalue expression with scalar type}}
785   // expected-note@+1 {{expected an expression statement}}
786   ;
787 
788   return T();
789 }
790 
acquire()791 int acquire() {
792   int a = 0, b = 0;
793 // Test for atomic acquire
794 // omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic write' cannot be used with 'acquire' clause}} omp50-note@+1 {{'acquire' clause used here}}
795 #pragma omp atomic write acquire
796   // 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}}
797   // expected-note@+1 {{expected an expression statement}}
798   ;
799 // omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
800 #pragma omp atomic seq_cst acquire
801   a += b;
802 
803 // omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic update' cannot be used with 'acquire' clause}} omp50-note@+1 {{'acquire' clause used here}}
804 #pragma omp atomic update acquire
805   // 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 lvalue expression with scalar type}}
806   // expected-note@+1 {{expected an expression statement}}
807   ;
808 
809  return acquire<int>(); // omp50-note {{in instantiation of function template specialization 'acquire<int>' requested here}}
810 }
811 
812 template <class T>
release()813 T release() {
814   T a = 0, b = 0;
815 // omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
816 #pragma omp atomic release
817   // 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 lvalue expression with scalar type}}
818   // expected-note@+1 {{expected an expression statement}}
819   ;
820 // omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'release' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
821 #pragma omp atomic release seq_cst
822   a += b;
823 
824 // omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
825 #pragma omp atomic update release
826   // 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 lvalue expression with scalar type}}
827   // expected-note@+1 {{expected an expression statement}}
828   ;
829 
830   return T();
831 }
832 
release()833 int release() {
834   int a = 0, b = 0;
835 // Test for atomic release
836 // omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} omp50-error@+1 {{directive '#pragma omp atomic read' cannot be used with 'release' clause}} omp50-note@+1 {{'release' clause used here}}
837 #pragma omp atomic read release
838   // 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}}
839   // expected-note@+1 {{expected an expression statement}}
840   ;
841 // omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
842 #pragma omp atomic seq_cst release
843   a += b;
844 
845 // omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
846 #pragma omp atomic update release
847   // 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 lvalue expression with scalar type}}
848   // expected-note@+1 {{expected an expression statement}}
849   ;
850 
851  return release<int>(); // omp50-note {{in instantiation of function template specialization 'release<int>' requested here}}
852 }
853 
854 template <class T>
relaxed()855 T relaxed() {
856   T a = 0, b = 0;
857 // omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
858 #pragma omp atomic relaxed
859   // 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 lvalue expression with scalar type}}
860   // expected-note@+1 {{expected an expression statement}}
861   ;
862 // omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'relaxed' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
863 #pragma omp atomic relaxed seq_cst
864   a += b;
865 
866 // omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
867 #pragma omp atomic update relaxed
868   // 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 lvalue expression with scalar type}}
869   // expected-note@+1 {{expected an expression statement}}
870   ;
871 
872   return T();
873 }
874 
relaxed()875 int relaxed() {
876   int a = 0, b = 0;
877 // Test for atomic relaxed
878 // omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
879 #pragma omp atomic read relaxed
880   // 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}}
881   // expected-note@+1 {{expected an expression statement}}
882   ;
883 // omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
884 #pragma omp atomic seq_cst relaxed
885   a += b;
886 
887 // omp45-error@+1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
888 #pragma omp atomic update relaxed
889   // 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 lvalue expression with scalar type}}
890   // expected-note@+1 {{expected an expression statement}}
891   ;
892 
893  return relaxed<int>(); // omp50-note {{in instantiation of function template specialization 'relaxed<int>' requested here}}
894 }
895 
896 template <class T>
mixed()897 T mixed() {
898   T a, b = T();
899 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
900 // expected-note@+1 2 {{'read' clause used here}}
901 #pragma omp atomic read write
902   a = b;
903 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
904 // expected-note@+1 2 {{'write' clause used here}}
905 #pragma omp atomic write read
906   a = b;
907 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
908 // expected-note@+1 2 {{'update' clause used here}}
909 #pragma omp atomic update read
910   a += b;
911 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
912 // expected-note@+1 2 {{'capture' clause used here}}
913 #pragma omp atomic capture read
914   a = ++b;
915   return T();
916 }
917 
mixed()918 int mixed() {
919   int a, b = 0;
920 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
921 // expected-note@+1 {{'read' clause used here}}
922 #pragma omp atomic read write
923   a = b;
924 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
925 // expected-note@+1 {{'write' clause used here}}
926 #pragma omp atomic write read
927   a = b;
928 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
929 // expected-note@+1 {{'write' clause used here}}
930 #pragma omp atomic write update
931   a = b;
932 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
933 // expected-note@+1 {{'write' clause used here}}
934 #pragma omp atomic write capture
935   a = b;
936   // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}}
937   return mixed<int>();
938 }
939 
940