1 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
2
foo()3 int foo() {
4 L1:
5 foo();
6 #pragma omp atomic
7 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
8 // expected-note@+1 {{expected an expression statement}}
9 {
10 foo();
11 goto L1; // expected-error {{use of undeclared label 'L1'}}
12 }
13 goto L2; // expected-error {{use of undeclared label 'L2'}}
14 #pragma omp atomic
15 // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
16 // expected-note@+1 {{expected an expression statement}}
17 {
18 foo();
19 L2:
20 foo();
21 }
22
23 return 0;
24 }
25
26 struct S {
27 int a;
28 };
29
readint()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
readS()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
writeint()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
writeS()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
updateint()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
captureint()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