Clang Project

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