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