1 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
2 
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;
28 };
29 
30 int readint() {
31   int a = 0, b = 0;
32 // Test for atomic read
33 #pragma omp atomic read
34   // 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}}
35   // expected-note@+1 {{expected an expression statement}}
36   ;
37 #pragma omp atomic read
38   // 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}}
39   // expected-note@+1 {{expected built-in assignment operator}}
40   foo();
41 #pragma omp atomic read
42   // 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}}
43   // expected-note@+1 {{expected built-in assignment operator}}
44   a += b;
45 #pragma omp atomic read
46   // 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}}
47   // expected-note@+1 {{expected lvalue expression}}
48   a = 0;
49 #pragma omp atomic read
50   a = b;
51   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
52 #pragma omp atomic read read
53   a = b;
54 
55   return 0;
56 }
57 
58 int readS() {
59   struct S a, b;
60   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
61 #pragma omp atomic read read
62   // 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}}
63   // expected-note@+1 {{expected expression of scalar type}}
64   a = b;
65 
66   return a.a;
67 }
68 
69 int writeint() {
70   int a = 0, b = 0;
71 // Test for atomic write
72 #pragma omp atomic write
73   // 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}}
74   // expected-note@+1 {{expected an expression statement}}
75   ;
76 #pragma omp atomic write
77   // 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}}
78   // expected-note@+1 {{expected built-in assignment operator}}
79   foo();
80 #pragma omp atomic write
81   // 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}}
82   // expected-note@+1 {{expected built-in assignment operator}}
83   a += b;
84 #pragma omp atomic write
85   a = 0;
86 #pragma omp atomic write
87   a = b;
88   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
89 #pragma omp atomic write write
90   a = b;
91 
92   return 0;
93 }
94 
95 int writeS() {
96   struct S a, b;
97   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
98 #pragma omp atomic write write
99   // 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}}
100   // expected-note@+1 {{expected expression of scalar type}}
101   a = b;
102 
103   return a.a;
104 }
105 
106 int updateint() {
107   int a = 0, b = 0;
108 // Test for atomic update
109 #pragma omp atomic update
110   // 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}}
111   // expected-note@+1 {{expected an expression statement}}
112   ;
113 #pragma omp atomic
114   // 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}}
115   // expected-note@+1 {{expected built-in binary or unary operator}}
116   foo();
117 #pragma omp atomic
118   // 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}}
119   // expected-note@+1 {{expected built-in binary operator}}
120   a = b;
121 #pragma omp atomic update
122   // 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}}
123   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
124   a = b || a;
125 #pragma omp atomic update
126   // 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}}
127   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
128   a = a && b;
129 #pragma omp atomic update
130   // 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}}
131   // expected-note@+1 {{expected in right hand side of expression}}
132   a = (float)a + b;
133 #pragma omp atomic
134   // 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}}
135   // expected-note@+1 {{expected in right hand side of expression}}
136   a = 2 * b;
137 #pragma omp atomic
138   // 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}}
139   // expected-note@+1 {{expected in right hand side of expression}}
140   a = b + *&a;
141 #pragma omp atomic update
142   *&a = *&a +  2;
143 #pragma omp atomic update
144   a++;
145 #pragma omp atomic
146   ++a;
147 #pragma omp atomic update
148   a--;
149 #pragma omp atomic
150   --a;
151 #pragma omp atomic update
152   a += b;
153 #pragma omp atomic
154   a %= b;
155 #pragma omp atomic update
156   a *= b;
157 #pragma omp atomic
158   a -= b;
159 #pragma omp atomic update
160   a /= b;
161 #pragma omp atomic
162   a &= b;
163 #pragma omp atomic update
164   a ^= b;
165 #pragma omp atomic
166   a |= b;
167 #pragma omp atomic update
168   a <<= b;
169 #pragma omp atomic
170   a >>= b;
171 #pragma omp atomic update
172   a = b + a;
173 #pragma omp atomic
174   a = a * b;
175 #pragma omp atomic update
176   a = b - a;
177 #pragma omp atomic
178   a = a / b;
179 #pragma omp atomic update
180   a = b & a;
181 #pragma omp atomic
182   a = a ^ b;
183 #pragma omp atomic update
184   a = b | a;
185 #pragma omp atomic
186   a = a << b;
187 #pragma omp atomic
188   a = b >> a;
189   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
190 #pragma omp atomic update update
191   a /= b;
192 
193   return 0;
194 }
195 
196 int captureint() {
197   int a = 0, b = 0, c = 0;
198 // Test for atomic capture
199 #pragma omp atomic capture
200   // 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}}
201   // expected-note@+1 {{expected compound statement}}
202   ;
203 #pragma omp atomic capture
204   // 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}}
205   // expected-note@+1 {{expected assignment expression}}
206   foo();
207 #pragma omp atomic capture
208   // 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}}
209   // expected-note@+1 {{expected built-in binary or unary operator}}
210   a = b;
211 #pragma omp atomic capture
212   // 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}}
213   // expected-note@+1 {{expected assignment expression}}
214   a = b || a;
215 #pragma omp atomic capture
216   // 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}}
217   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
218   b = a = a && b;
219 #pragma omp atomic capture
220   // 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}}
221   // expected-note@+1 {{expected assignment expression}}
222   a = (float)a + b;
223 #pragma omp atomic capture
224   // 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}}
225   // expected-note@+1 {{expected assignment expression}}
226   a = 2 * b;
227 #pragma omp atomic capture
228   // 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}}
229   // expected-note@+1 {{expected assignment expression}}
230   a = b + *&a;
231 #pragma omp atomic capture
232   // 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}}
233   // expected-note@+1 {{expected exactly two expression statements}}
234   { a = b; }
235 #pragma omp atomic capture
236   // 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}}
237   // expected-note@+1 {{expected exactly two expression statements}}
238   {}
239 #pragma omp atomic capture
240   // 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}}
241   // expected-note@+1 {{expected in right hand side of the first expression}}
242   {a = b;a = b;}
243 #pragma omp atomic capture
244   // 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}}
245   // expected-note@+1 {{expected in right hand side of the first expression}}
246   {a = b; a = b || a;}
247 #pragma omp atomic capture
248   {b = a; a = a && b;}
249 #pragma omp atomic capture
250   // 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}}
251   // expected-note@+1 {{expected in right hand side of expression}}
252   b = a = (float)a + b;
253 #pragma omp atomic capture
254   // 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}}
255   // expected-note@+1 {{expected in right hand side of expression}}
256   b = a = 2 * b;
257 #pragma omp atomic capture
258   // 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}}
259   // expected-note@+1 {{expected in right hand side of expression}}
260   b = a = b + *&a;
261 #pragma omp atomic capture
262   c = *&a = *&a +  2;
263 #pragma omp atomic capture
264   c = a++;
265 #pragma omp atomic capture
266   c = ++a;
267 #pragma omp atomic capture
268   c = a--;
269 #pragma omp atomic capture
270   c = --a;
271 #pragma omp atomic capture
272   c = a += b;
273 #pragma omp atomic capture
274   c = a %= b;
275 #pragma omp atomic capture
276   c = a *= b;
277 #pragma omp atomic capture
278   c = a -= b;
279 #pragma omp atomic capture
280   c = a /= b;
281 #pragma omp atomic capture
282   c = a &= b;
283 #pragma omp atomic capture
284   c = a ^= b;
285 #pragma omp atomic capture
286   c = a |= b;
287 #pragma omp atomic capture
288   c = a <<= b;
289 #pragma omp atomic capture
290   c = a >>= b;
291 #pragma omp atomic capture
292   c = a = b + a;
293 #pragma omp atomic capture
294   c = a = a * b;
295 #pragma omp atomic capture
296   c = a = b - a;
297 #pragma omp atomic capture
298   c = a = a / b;
299 #pragma omp atomic capture
300   c = a = b & a;
301 #pragma omp atomic capture
302   c = a = a ^ b;
303 #pragma omp atomic capture
304   c = a = b | a;
305 #pragma omp atomic capture
306   c = a = a << b;
307 #pragma omp atomic capture
308   c = a = b >> a;
309 #pragma omp atomic capture
310   { c = *&a; *&a = *&a +  2;}
311 #pragma omp atomic capture
312   { *&a = *&a +  2; c = *&a;}
313 #pragma omp atomic capture
314   {c = a; a++;}
315 #pragma omp atomic capture
316   {++a;c = a;}
317 #pragma omp atomic capture
318   {c = a;a--;}
319 #pragma omp atomic capture
320   {--a;c = a;}
321 #pragma omp atomic capture
322   {c = a; a += b;}
323 #pragma omp atomic capture
324   {a %= b; c = a;}
325 #pragma omp atomic capture
326   {c = a; a *= b;}
327 #pragma omp atomic capture
328   {a -= b;c = a;}
329 #pragma omp atomic capture
330   {c = a; a /= b;}
331 #pragma omp atomic capture
332   {a &= b; c = a;}
333 #pragma omp atomic capture
334   {c = a; a ^= b;}
335 #pragma omp atomic capture
336   {a |= b; c = a;}
337 #pragma omp atomic capture
338   {c = a; a <<= b;}
339 #pragma omp atomic capture
340   {a >>= b; c = a;}
341 #pragma omp atomic capture
342   {c = a; a = b + a;}
343 #pragma omp atomic capture
344   {a = a * b; c = a;}
345 #pragma omp atomic capture
346   {c = a; a = b - a;}
347 #pragma omp atomic capture
348   {a = a / b; c = a;}
349 #pragma omp atomic capture
350   {c = a; a = b & a;}
351 #pragma omp atomic capture
352   {a = a ^ b; c = a;}
353 #pragma omp atomic capture
354   {c = a; a = b | a;}
355 #pragma omp atomic capture
356   {a = a << b; c = a;}
357 #pragma omp atomic capture
358   {c = a; a = b >> a;}
359 #pragma omp atomic capture
360   {c = a; a = foo();}
361   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
362 #pragma omp atomic capture capture
363   b = a /= b;
364 
365   return 0;
366 }
367 
368