1// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
2
3int foo() {
4L1:
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
26struct S {
27  int a;
28};
29
30int 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
58int 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
69int 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
95int 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
106int 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
196int 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