1 // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
2 // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -ferror-limit 100 %s -Wuninitialized
3 
4 // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
5 // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
6 
xxx(int argc)7 void xxx(int argc) {
8   int x; // expected-note {{initialize the variable 'x' to silence this warning}}
9 #pragma omp atomic read
10   argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
11 }
12 
foo()13 int foo() {
14 L1:
15   foo();
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 lvalue expression with scalar type}}
18   // expected-note@+1 {{expected an expression statement}}
19   {
20     foo();
21     goto L1;
22   }
23   goto L2;
24 #pragma omp atomic
25   // 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 lvalue expression with scalar type}}
26   // expected-note@+1 {{expected an expression statement}}
27   {
28     foo();
29   L2:
30     foo();
31   }
32 
33   return 0;
34 }
35 
36 struct S {
37   int a;
38 };
39 
readint()40 int readint() {
41   int a = 0, b = 0;
42 // Test for atomic read
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 an expression statement}}
46   ;
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 built-in assignment operator}}
50   foo();
51 #pragma omp atomic read
52   // 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}}
53   // expected-note@+1 {{expected built-in assignment operator}}
54   a += b;
55 #pragma omp atomic read
56   // 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}}
57   // expected-note@+1 {{expected lvalue expression}}
58   a = 0;
59 #pragma omp atomic read
60   a = b;
61   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
62 #pragma omp atomic read read
63   a = b;
64 
65   return 0;
66 }
67 
readS()68 int readS() {
69   struct S a, b;
70   // 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'}}
71 #pragma omp atomic read read allocate(a)
72   // 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}}
73   // expected-note@+1 {{expected expression of scalar type}}
74   a = b;
75 
76   return a.a;
77 }
78 
writeint()79 int writeint() {
80   int a = 0, b = 0;
81 // Test for atomic write
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 an expression statement}}
85   ;
86 #pragma omp atomic write
87   // 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}}
88   // expected-note@+1 {{expected built-in assignment operator}}
89   foo();
90 #pragma omp atomic write
91   // 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}}
92   // expected-note@+1 {{expected built-in assignment operator}}
93   a += b;
94 #pragma omp atomic write
95   a = 0;
96 #pragma omp atomic write
97   a = b;
98   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
99 #pragma omp atomic write write
100   a = b;
101 
102   return 0;
103 }
104 
writeS()105 int writeS() {
106   struct S a, b;
107   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
108 #pragma omp atomic write write
109   // 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}}
110   // expected-note@+1 {{expected expression of scalar type}}
111   a = b;
112 
113   return a.a;
114 }
115 
updateint()116 int updateint() {
117   int a = 0, b = 0;
118 // Test for atomic update
119 #pragma omp atomic update
120   // 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 lvalue expression with scalar type}}
121   // expected-note@+1 {{expected an expression statement}}
122   ;
123 #pragma omp atomic
124   // 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 lvalue expression with scalar type}}
125   // expected-note@+1 {{expected built-in binary or unary operator}}
126   foo();
127 #pragma omp atomic
128   // 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 lvalue expression with scalar type}}
129   // expected-note@+1 {{expected built-in binary operator}}
130   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 lvalue expression with scalar type}}
133   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
134   a = b || a;
135 #pragma omp atomic update
136   // 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 lvalue expression with scalar type}}
137   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
138   a = a && b;
139 #pragma omp atomic update
140   // 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 lvalue expression with scalar type}}
141   // expected-note@+1 {{expected in right hand side of expression}}
142   a = (float)a + b;
143 #pragma omp atomic
144   // 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 lvalue expression with scalar type}}
145   // expected-note@+1 {{expected in right hand side of expression}}
146   a = 2 * b;
147 #pragma omp atomic
148   // 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 lvalue expression with scalar type}}
149   // expected-note@+1 {{expected in right hand side of expression}}
150   a = b + *&a;
151 #pragma omp atomic update
152   *&a = *&a +  2;
153 #pragma omp atomic update
154   a++;
155 #pragma omp atomic
156   ++a;
157 #pragma omp atomic update
158   a--;
159 #pragma omp atomic
160   --a;
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;
175 #pragma omp atomic
176   a |= b;
177 #pragma omp atomic update
178   a <<= b;
179 #pragma omp atomic
180   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 update
190   a = b & a;
191 #pragma omp atomic
192   a = a ^ b;
193 #pragma omp atomic update
194   a = b | a;
195 #pragma omp atomic
196   a = a << b;
197 #pragma omp atomic
198   a = b >> a;
199   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
200 #pragma omp atomic update update
201   a /= b;
202 
203   return 0;
204 }
205 
captureint()206 int captureint() {
207   int a = 0, b = 0, c = 0;
208 // Test for atomic capture
209 #pragma omp atomic capture
210   // 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 lvalue expression with scalar type}}
211   // expected-note@+1 {{expected compound statement}}
212   ;
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 lvalue expressions with scalar type}}
215   // expected-note@+1 {{expected assignment expression}}
216   foo();
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 lvalue expressions with scalar type}}
219   // expected-note@+1 {{expected built-in binary or unary operator}}
220   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 lvalue expressions with scalar type}}
223   // expected-note@+1 {{expected assignment expression}}
224   a = b || a;
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 lvalue expressions with scalar type}}
227   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
228   b = a = a && 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 lvalue expressions with scalar type}}
231   // expected-note@+1 {{expected assignment expression}}
232   a = (float)a + b;
233 #pragma omp atomic capture
234   // 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 lvalue expressions with scalar type}}
235   // expected-note@+1 {{expected assignment expression}}
236   a = 2 * b;
237 #pragma omp atomic capture
238   // 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 lvalue expressions with scalar type}}
239   // expected-note@+1 {{expected assignment expression}}
240   a = b + *&a;
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 lvalue expression with scalar type}}
243   // expected-note@+1 {{expected exactly two expression statements}}
244   { 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 lvalue expression with scalar type}}
247   // expected-note@+1 {{expected exactly two expression statements}}
248   {}
249 #pragma omp atomic capture
250   // 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 lvalue expression with scalar type}}
251   // expected-note@+1 {{expected in right hand side of the first expression}}
252   {a = b;a = b;}
253 #pragma omp atomic capture
254   // 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 lvalue expression with scalar type}}
255   // expected-note@+1 {{expected in right hand side of the first expression}}
256   {a = b; a = b || a;}
257 #pragma omp atomic capture
258   {b = a; a = a && 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 lvalue expressions with scalar type}}
261   // expected-note@+1 {{expected in right hand side of expression}}
262   b = a = (float)a + b;
263 #pragma omp atomic capture
264   // 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 lvalue expressions with scalar type}}
265   // expected-note@+1 {{expected in right hand side of expression}}
266   b = a = 2 * b;
267 #pragma omp atomic capture
268   // 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 lvalue expressions with scalar type}}
269   // expected-note@+1 {{expected in right hand side of expression}}
270   b = a = b + *&a;
271 #pragma omp atomic capture
272   c = *&a = *&a +  2;
273 #pragma omp atomic capture
274   c = a++;
275 #pragma omp atomic capture
276   c = ++a;
277 #pragma omp atomic capture
278   c = a--;
279 #pragma omp atomic capture
280   c = --a;
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;
295 #pragma omp atomic capture
296   c = a |= b;
297 #pragma omp atomic capture
298   c = a <<= b;
299 #pragma omp atomic capture
300   c = 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 ^ b;
313 #pragma omp atomic capture
314   c = a = b | a;
315 #pragma omp atomic capture
316   c = a = a << b;
317 #pragma omp atomic capture
318   c = a = b >> a;
319 #pragma omp atomic capture
320   { c = *&a; *&a = *&a +  2;}
321 #pragma omp atomic capture
322   { *&a = *&a +  2; c = *&a;}
323 #pragma omp atomic capture
324   {c = a; a++;}
325 #pragma omp atomic capture
326   {c = a; (a)++;}
327 #pragma omp atomic capture
328   {++a;c = a;}
329 #pragma omp atomic capture
330   {c = a;a--;}
331 #pragma omp atomic capture
332   {--a;c = a;}
333 #pragma omp atomic capture
334   {c = a; a += b;}
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;}
349 #pragma omp atomic capture
350   {a |= b; c = a;}
351 #pragma omp atomic capture
352   {c = a; a <<= b;}
353 #pragma omp atomic capture
354   {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   {a = a ^ b; c = a;}
367 #pragma omp atomic capture
368   {c = a; a = b | a;}
369 #pragma omp atomic capture
370   {a = a << b; c = a;}
371 #pragma omp atomic capture
372   {c = a; a = b >> a;}
373 #pragma omp atomic capture
374   {c = a; a = foo();}
375   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
376 #pragma omp atomic capture capture
377   b = a /= b;
378 
379   return 0;
380 }
381 
hint()382 void hint() {
383   int a = 0;
384 #pragma omp atomic hint // omp45-error {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} expected-error {{expected '(' after 'hint'}}
385   a += 1;
386 #pragma omp atomic hint( // omp45-error {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
387   a += 1;
388 #pragma omp atomic hint(+ // omp45-error {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
389   a += 1;
390 #pragma omp atomic hint(a // omp45-error {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{integer constant expression}}
391   a += 1;
392 #pragma omp atomic hint(a) // omp45-error {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} omp50-error {{integer constant expression}}
393   a += 1;
394 #pragma omp atomic hint(1) hint(1) // omp45-error 2 {{unexpected OpenMP clause 'hint' in directive '#pragma omp atomic'}} expected-error {{directive '#pragma omp atomic' cannot contain more than one 'hint' clause}}
395   a += 1;
396 }
397