1 | // RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s -Wno-openmp-target |
2 | |
3 | // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s -Wno-openmp-target |
4 | |
5 | class S { |
6 | int a; |
7 | S() : a(0) {} // expected-note {{implicitly declared private here}} |
8 | |
9 | public: |
10 | S(int v) : a(v) {} |
11 | S(const S &s) : a(s.a) {} |
12 | }; |
13 | |
14 | static int sii; |
15 | // expected-note@+1 {{defined as threadprivate or thread local}} |
16 | #pragma omp threadprivate(sii) |
17 | static int globalii; |
18 | |
19 | int test_iteration_spaces() { |
20 | const int N = 100; |
21 | float a[N], b[N], c[N]; |
22 | int ii, jj, kk; |
23 | float fii; |
24 | double dii; |
25 | #pragma omp target |
26 | #pragma omp teams |
27 | #pragma omp distribute parallel for simd |
28 | for (int i = 0; i < 10; i += 1) { |
29 | c[i] = a[i] + b[i]; |
30 | } |
31 | #pragma omp target |
32 | #pragma omp teams |
33 | #pragma omp distribute parallel for simd |
34 | for (char i = 0; i < 10; i++) { |
35 | c[i] = a[i] + b[i]; |
36 | } |
37 | #pragma omp target |
38 | #pragma omp teams |
39 | #pragma omp distribute parallel for simd |
40 | for (char i = 0; i < 10; i += '\1') { |
41 | c[i] = a[i] + b[i]; |
42 | } |
43 | #pragma omp target |
44 | #pragma omp teams |
45 | #pragma omp distribute parallel for simd |
46 | for (long long i = 0; i < 10; i++) { |
47 | c[i] = a[i] + b[i]; |
48 | } |
49 | #pragma omp target |
50 | #pragma omp teams |
51 | // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} |
52 | #pragma omp distribute parallel for simd |
53 | for (long long i = 0; i < 10; i += 1.5) { |
54 | c[i] = a[i] + b[i]; |
55 | } |
56 | #pragma omp target |
57 | #pragma omp teams |
58 | #pragma omp distribute parallel for simd |
59 | for (long long i = 0; i < 'z'; i += 1u) { |
60 | c[i] = a[i] + b[i]; |
61 | } |
62 | #pragma omp target |
63 | #pragma omp teams |
64 | // expected-error@+2 {{variable must be of integer or random access iterator type}} |
65 | #pragma omp distribute parallel for simd |
66 | for (float fi = 0; fi < 10.0; fi++) { |
67 | c[(int)fi] = a[(int)fi] + b[(int)fi]; |
68 | } |
69 | #pragma omp target |
70 | #pragma omp teams |
71 | // expected-error@+2 {{variable must be of integer or random access iterator type}} |
72 | #pragma omp distribute parallel for simd |
73 | for (double fi = 0; fi < 10.0; fi++) { |
74 | c[(int)fi] = a[(int)fi] + b[(int)fi]; |
75 | } |
76 | #pragma omp target |
77 | #pragma omp teams |
78 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
79 | #pragma omp distribute parallel for simd |
80 | for (int &ref = ii; ref < 10; ref++) { |
81 | } |
82 | #pragma omp target |
83 | #pragma omp teams |
84 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
85 | #pragma omp distribute parallel for simd |
86 | for (int i; i < 10; i++) |
87 | c[i] = a[i]; |
88 | |
89 | #pragma omp target |
90 | #pragma omp teams |
91 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
92 | #pragma omp distribute parallel for simd |
93 | for (int i = 0, j = 0; i < 10; ++i) |
94 | c[i] = a[i]; |
95 | |
96 | #pragma omp target |
97 | #pragma omp teams |
98 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
99 | #pragma omp distribute parallel for simd |
100 | for (; ii < 10; ++ii) |
101 | c[ii] = a[ii]; |
102 | |
103 | #pragma omp target |
104 | #pragma omp teams |
105 | // expected-warning@+3 {{expression result unused}} |
106 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
107 | #pragma omp distribute parallel for simd |
108 | for (ii + 1; ii < 10; ++ii) |
109 | c[ii] = a[ii]; |
110 | |
111 | #pragma omp target |
112 | #pragma omp teams |
113 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
114 | #pragma omp distribute parallel for simd |
115 | for (c[ii] = 0; ii < 10; ++ii) |
116 | c[ii] = a[ii]; |
117 | |
118 | #pragma omp target |
119 | #pragma omp teams |
120 | // Ok to skip parenthesises. |
121 | #pragma omp distribute parallel for simd |
122 | for (((ii)) = 0; ii < 10; ++ii) |
123 | c[ii] = a[ii]; |
124 | |
125 | #pragma omp target |
126 | #pragma omp teams |
127 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} |
128 | #pragma omp distribute parallel for simd |
129 | for (int i = 0; i; i++) |
130 | c[i] = a[i]; |
131 | |
132 | #pragma omp target |
133 | #pragma omp teams |
134 | // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} |
135 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} |
136 | #pragma omp distribute parallel for simd |
137 | for (int i = 0; jj < kk; ii++) |
138 | c[i] = a[i]; |
139 | |
140 | #pragma omp target |
141 | #pragma omp teams |
142 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} |
143 | #pragma omp distribute parallel for simd |
144 | for (int i = 0; !!i; i++) |
145 | c[i] = a[i]; |
146 | |
147 | // Ok |
148 | #pragma omp target |
149 | #pragma omp teams |
150 | #pragma omp distribute parallel for simd |
151 | for (int i = 0; i != 1; i++) |
152 | c[i] = a[i]; |
153 | |
154 | #pragma omp target |
155 | #pragma omp teams |
156 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} |
157 | #pragma omp distribute parallel for simd |
158 | for (int i = 0;; i++) |
159 | c[i] = a[i]; |
160 | |
161 | // Ok. |
162 | #pragma omp target |
163 | #pragma omp teams |
164 | #pragma omp distribute parallel for simd |
165 | for (int i = 11; i > 10; i--) |
166 | c[i] = a[i]; |
167 | |
168 | // Ok. |
169 | #pragma omp target |
170 | #pragma omp teams |
171 | #pragma omp distribute parallel for simd |
172 | for (int i = 0; i < 10; ++i) |
173 | c[i] = a[i]; |
174 | |
175 | // Ok. |
176 | #pragma omp target |
177 | #pragma omp teams |
178 | #pragma omp distribute parallel for simd |
179 | for (ii = 0; ii < 10; ++ii) |
180 | c[ii] = a[ii]; |
181 | |
182 | #pragma omp target |
183 | #pragma omp teams |
184 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
185 | #pragma omp distribute parallel for simd |
186 | for (ii = 0; ii < 10; ++jj) |
187 | c[ii] = a[jj]; |
188 | |
189 | #pragma omp target |
190 | #pragma omp teams |
191 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
192 | #pragma omp distribute parallel for simd |
193 | for (ii = 0; ii < 10; ++++ii) |
194 | c[ii] = a[ii]; |
195 | |
196 | // Ok but undefined behavior (in general, cannot check that incr |
197 | // is really loop-invariant). |
198 | #pragma omp target |
199 | #pragma omp teams |
200 | #pragma omp distribute parallel for simd |
201 | for (ii = 0; ii < 10; ii = ii + ii) |
202 | c[ii] = a[ii]; |
203 | |
204 | #pragma omp target |
205 | #pragma omp teams |
206 | // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} |
207 | #pragma omp distribute parallel for simd |
208 | for (ii = 0; ii < 10; ii = ii + 1.0f) |
209 | c[ii] = a[ii]; |
210 | |
211 | // Ok - step was converted to integer type. |
212 | #pragma omp target |
213 | #pragma omp teams |
214 | #pragma omp distribute parallel for simd |
215 | for (ii = 0; ii < 10; ii = ii + (int)1.1f) |
216 | c[ii] = a[ii]; |
217 | |
218 | #pragma omp target |
219 | #pragma omp teams |
220 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
221 | #pragma omp distribute parallel for simd |
222 | for (ii = 0; ii < 10; jj = ii + 2) |
223 | c[ii] = a[ii]; |
224 | |
225 | #pragma omp target |
226 | #pragma omp teams |
227 | // expected-warning@+3 {{relational comparison result unused}} |
228 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
229 | #pragma omp distribute parallel for simd |
230 | for (ii = 0; ii<10; jj> kk + 2) |
231 | c[ii] = a[ii]; |
232 | |
233 | #pragma omp target |
234 | #pragma omp teams |
235 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
236 | #pragma omp distribute parallel for simd |
237 | for (ii = 0; ii < 10;) |
238 | c[ii] = a[ii]; |
239 | |
240 | #pragma omp target |
241 | #pragma omp teams |
242 | // expected-warning@+3 {{expression result unused}} |
243 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
244 | #pragma omp distribute parallel for simd |
245 | for (ii = 0; ii < 10; !ii) |
246 | c[ii] = a[ii]; |
247 | |
248 | #pragma omp target |
249 | #pragma omp teams |
250 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
251 | #pragma omp distribute parallel for simd |
252 | for (ii = 0; ii < 10; ii ? ++ii : ++jj) |
253 | c[ii] = a[ii]; |
254 | |
255 | #pragma omp target |
256 | #pragma omp teams |
257 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} |
258 | #pragma omp distribute parallel for simd |
259 | for (ii = 0; ii < 10; ii = ii < 10) |
260 | c[ii] = a[ii]; |
261 | |
262 | #pragma omp target |
263 | #pragma omp teams |
264 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
265 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
266 | #pragma omp distribute parallel for simd |
267 | for (ii = 0; ii < 10; ii = ii + 0) |
268 | c[ii] = a[ii]; |
269 | |
270 | #pragma omp target |
271 | #pragma omp teams |
272 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
273 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
274 | #pragma omp distribute parallel for simd |
275 | for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) |
276 | c[ii] = a[ii]; |
277 | |
278 | #pragma omp target |
279 | #pragma omp teams |
280 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
281 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
282 | #pragma omp distribute parallel for simd |
283 | for (ii = 0; (ii) < 10; ii -= 25) |
284 | c[ii] = a[ii]; |
285 | |
286 | #pragma omp target |
287 | #pragma omp teams |
288 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
289 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
290 | #pragma omp distribute parallel for simd |
291 | for (ii = 0; (ii < 10); ii -= 0) |
292 | c[ii] = a[ii]; |
293 | |
294 | #pragma omp target |
295 | #pragma omp teams |
296 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
297 | // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} |
298 | #pragma omp distribute parallel for simd |
299 | for (ii = 0; ii > 10; (ii += 0)) |
300 | c[ii] = a[ii]; |
301 | |
302 | #pragma omp target |
303 | #pragma omp teams |
304 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
305 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
306 | #pragma omp distribute parallel for simd |
307 | for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) |
308 | c[ii] = a[ii]; |
309 | |
310 | #pragma omp target |
311 | #pragma omp teams |
312 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
313 | // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} |
314 | #pragma omp distribute parallel for simd |
315 | for ((ii = 0); ii > 10; (ii -= 0)) |
316 | c[ii] = a[ii]; |
317 | |
318 | #pragma omp target |
319 | #pragma omp teams |
320 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
321 | // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} |
322 | #pragma omp distribute parallel for simd |
323 | for (ii = 0; (ii < 10); (ii -= 0)) |
324 | c[ii] = a[ii]; |
325 | |
326 | #pragma omp target |
327 | #pragma omp teams |
328 | // expected-note@+2 {{defined as firstprivate}} |
329 | // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}} |
330 | #pragma omp distribute parallel for simd firstprivate(ii) |
331 | for (ii = 0; ii < 10; ii++) |
332 | c[ii] = a[ii]; |
333 | |
334 | #pragma omp target |
335 | #pragma omp teams |
336 | #pragma omp distribute parallel for simd linear(ii) |
337 | for (ii = 0; ii < 10; ii++) |
338 | c[ii] = a[ii]; |
339 | |
340 | #pragma omp target |
341 | #pragma omp teams |
342 | // expected-note@+2 {{defined as private}} |
343 | // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be private, predetermined as linear}} |
344 | #pragma omp distribute parallel for simd private(ii) |
345 | for (ii = 0; ii < 10; ii++) |
346 | c[ii] = a[ii]; |
347 | |
348 | #pragma omp target |
349 | #pragma omp teams |
350 | // expected-note@+2 {{defined as lastprivate}} |
351 | // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be lastprivate, predetermined as linear}} |
352 | #pragma omp distribute parallel for simd lastprivate(ii) |
353 | for (ii = 0; ii < 10; ii++) |
354 | c[ii] = a[ii]; |
355 | |
356 | { |
357 | // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}} |
358 | #pragma omp distribute parallel for simd |
359 | for (sii = 0; sii < 10; sii += 1) |
360 | c[sii] = a[sii]; |
361 | } |
362 | |
363 | { |
364 | #pragma omp distribute parallel for simd |
365 | for (globalii = 0; globalii < 10; globalii += 1) |
366 | c[globalii] = a[globalii]; |
367 | } |
368 | |
369 | { |
370 | #pragma omp target |
371 | #pragma omp teams |
372 | #pragma omp distribute parallel for simd collapse(2) |
373 | for (ii = 0; ii < 10; ii += 1) |
374 | for (globalii = 0; globalii < 10; globalii += 1) |
375 | c[globalii] += a[globalii] + ii; |
376 | } |
377 | |
378 | #pragma omp target |
379 | #pragma omp teams |
380 | // expected-error@+2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}} |
381 | #pragma omp distribute parallel for simd |
382 | for (auto &item : a) { |
383 | item = item + 1; |
384 | } |
385 | |
386 | #pragma omp target |
387 | #pragma omp teams |
388 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
389 | // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} |
390 | #pragma omp distribute parallel for simd |
391 | for (unsigned i = 9; i < 10; i--) { |
392 | c[i] = a[i] + b[i]; |
393 | } |
394 | |
395 | int(*lb)[4] = nullptr; |
396 | #pragma omp target |
397 | #pragma omp teams |
398 | #pragma omp distribute parallel for simd |
399 | for (int(*p)[4] = lb; p < lb + 8; ++p) { |
400 | } |
401 | |
402 | #pragma omp target |
403 | #pragma omp teams |
404 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
405 | #pragma omp distribute parallel for simd |
406 | for (int a{0}; a < 10; ++a) { |
407 | } |
408 | |
409 | return 0; |
410 | } |
411 | |
412 | // Iterators allowed in openmp for-loops. |
413 | namespace std { |
414 | struct random_access_iterator_tag {}; |
415 | template <class Iter> |
416 | struct iterator_traits { |
417 | typedef typename Iter::difference_type difference_type; |
418 | typedef typename Iter::iterator_category iterator_category; |
419 | }; |
420 | template <class Iter> |
421 | typename iterator_traits<Iter>::difference_type |
422 | distance(Iter first, Iter last) { return first - last; } |
423 | } |
424 | class Iter0 { |
425 | public: |
426 | Iter0() {} |
427 | Iter0(const Iter0 &) {} |
428 | Iter0 operator++() { return *this; } |
429 | Iter0 operator--() { return *this; } |
430 | bool operator<(Iter0 a) { return true; } |
431 | }; |
432 | // expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} |
433 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} |
434 | int operator-(Iter0 a, Iter0 b) { return 0; } |
435 | class Iter1 { |
436 | public: |
437 | Iter1(float f = 0.0f, double d = 0.0) {} |
438 | Iter1(const Iter1 &) {} |
439 | Iter1 operator++() { return *this; } |
440 | Iter1 operator--() { return *this; } |
441 | bool operator<(Iter1 a) { return true; } |
442 | bool operator>=(Iter1 a) { return false; } |
443 | }; |
444 | class GoodIter { |
445 | public: |
446 | GoodIter() {} |
447 | GoodIter(const GoodIter &) {} |
448 | GoodIter(int fst, int snd) {} |
449 | GoodIter &operator=(const GoodIter &that) { return *this; } |
450 | GoodIter &operator=(const Iter0 &that) { return *this; } |
451 | GoodIter &operator+=(int x) { return *this; } |
452 | explicit GoodIter(void *) {} |
453 | GoodIter operator++() { return *this; } |
454 | GoodIter operator--() { return *this; } |
455 | bool operator!() { return true; } |
456 | bool operator<(GoodIter a) { return true; } |
457 | bool operator<=(GoodIter a) { return true; } |
458 | bool operator>=(GoodIter a) { return false; } |
459 | typedef int difference_type; |
460 | typedef std::random_access_iterator_tag iterator_category; |
461 | }; |
462 | // expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} |
463 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} |
464 | int operator-(GoodIter a, GoodIter b) { return 0; } |
465 | // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} |
466 | GoodIter operator-(GoodIter a) { return a; } |
467 | // expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} |
468 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} |
469 | GoodIter operator-(GoodIter a, int v) { return GoodIter(); } |
470 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} |
471 | GoodIter operator+(GoodIter a, int v) { return GoodIter(); } |
472 | // expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} |
473 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} |
474 | GoodIter operator-(int v, GoodIter a) { return GoodIter(); } |
475 | // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}} |
476 | GoodIter operator+(int v, GoodIter a) { return GoodIter(); } |
477 | |
478 | int test_with_random_access_iterator() { |
479 | GoodIter begin, end; |
480 | Iter0 begin0, end0; |
481 | #pragma omp target |
482 | #pragma omp teams |
483 | #pragma omp distribute parallel for simd |
484 | for (GoodIter I = begin; I < end; ++I) |
485 | ++I; |
486 | #pragma omp target |
487 | #pragma omp teams |
488 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
489 | #pragma omp distribute parallel for simd |
490 | for (GoodIter &I = begin; I < end; ++I) |
491 | ++I; |
492 | #pragma omp target |
493 | #pragma omp teams |
494 | #pragma omp distribute parallel for simd |
495 | for (GoodIter I = begin; I >= end; --I) |
496 | ++I; |
497 | #pragma omp target |
498 | #pragma omp teams |
499 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
500 | #pragma omp distribute parallel for simd |
501 | for (GoodIter I(begin); I < end; ++I) |
502 | ++I; |
503 | #pragma omp target |
504 | #pragma omp teams |
505 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
506 | #pragma omp distribute parallel for simd |
507 | for (GoodIter I(nullptr); I < end; ++I) |
508 | ++I; |
509 | #pragma omp target |
510 | #pragma omp teams |
511 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
512 | #pragma omp distribute parallel for simd |
513 | for (GoodIter I(0); I < end; ++I) |
514 | ++I; |
515 | #pragma omp target |
516 | #pragma omp teams |
517 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
518 | #pragma omp distribute parallel for simd |
519 | for (GoodIter I(1, 2); I < end; ++I) |
520 | ++I; |
521 | #pragma omp target |
522 | #pragma omp teams |
523 | #pragma omp distribute parallel for simd |
524 | for (begin = GoodIter(0); begin < end; ++begin) |
525 | ++begin; |
526 | #pragma omp target |
527 | #pragma omp teams |
528 | // expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} |
529 | // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} |
530 | #pragma omp distribute parallel for simd |
531 | for (begin = begin0; begin < end; ++begin) |
532 | ++begin; |
533 | #pragma omp target |
534 | #pragma omp teams |
535 | // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
536 | #pragma omp distribute parallel for simd |
537 | for (++begin; begin < end; ++begin) |
538 | ++begin; |
539 | #pragma omp target |
540 | #pragma omp teams |
541 | #pragma omp distribute parallel for simd |
542 | for (begin = end; begin < end; ++begin) |
543 | ++begin; |
544 | #pragma omp target |
545 | #pragma omp teams |
546 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} |
547 | #pragma omp distribute parallel for simd |
548 | for (GoodIter I = begin; I - I; ++I) |
549 | ++I; |
550 | #pragma omp target |
551 | #pragma omp teams |
552 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} |
553 | #pragma omp distribute parallel for simd |
554 | for (GoodIter I = begin; begin < end; ++I) |
555 | ++I; |
556 | #pragma omp target |
557 | #pragma omp teams |
558 | // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} |
559 | #pragma omp distribute parallel for simd |
560 | for (GoodIter I = begin; !I; ++I) |
561 | ++I; |
562 | #pragma omp target |
563 | #pragma omp teams |
564 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
565 | // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
566 | #pragma omp distribute parallel for simd |
567 | for (GoodIter I = begin; I >= end; I = I + 1) |
568 | ++I; |
569 | #pragma omp target |
570 | #pragma omp teams |
571 | #pragma omp distribute parallel for simd |
572 | for (GoodIter I = begin; I >= end; I = I - 1) |
573 | ++I; |
574 | #pragma omp target |
575 | #pragma omp teams |
576 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} |
577 | #pragma omp distribute parallel for simd |
578 | for (GoodIter I = begin; I >= end; I = -I) |
579 | ++I; |
580 | #pragma omp target |
581 | #pragma omp teams |
582 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
583 | // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
584 | #pragma omp distribute parallel for simd |
585 | for (GoodIter I = begin; I >= end; I = 2 + I) |
586 | ++I; |
587 | #pragma omp target |
588 | #pragma omp teams |
589 | // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}} |
590 | #pragma omp distribute parallel for simd |
591 | for (GoodIter I = begin; I >= end; I = 2 - I) |
592 | ++I; |
593 | #pragma omp target |
594 | #pragma omp teams |
595 | // expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} |
596 | #pragma omp distribute parallel for simd |
597 | for (Iter0 I = begin0; I < end0; ++I) |
598 | ++I; |
599 | #pragma omp target |
600 | #pragma omp teams |
601 | // Initializer is constructor without params. |
602 | // expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} |
603 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
604 | #pragma omp distribute parallel for simd |
605 | for (Iter0 I; I < end0; ++I) |
606 | ++I; |
607 | Iter1 begin1, end1; |
608 | #pragma omp target |
609 | #pragma omp teams |
610 | // expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} |
611 | // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} |
612 | #pragma omp distribute parallel for simd |
613 | for (Iter1 I = begin1; I < end1; ++I) |
614 | ++I; |
615 | #pragma omp target |
616 | #pragma omp teams |
617 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
618 | // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
619 | #pragma omp distribute parallel for simd |
620 | for (Iter1 I = begin1; I >= end1; ++I) |
621 | ++I; |
622 | #pragma omp target |
623 | #pragma omp teams |
624 | // expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}} |
625 | // expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} |
626 | // Initializer is constructor with all default params. |
627 | // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} |
628 | #pragma omp distribute parallel for simd |
629 | for (Iter1 I; I < end1; ++I) { |
630 | } |
631 | return 0; |
632 | } |
633 | |
634 | template <typename IT, int ST> |
635 | class TC { |
636 | public: |
637 | int dotest_lt(IT begin, IT end) { |
638 | #pragma omp target |
639 | #pragma omp teams |
640 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
641 | // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} |
642 | #pragma omp distribute parallel for simd |
643 | for (IT I = begin; I < end; I = I + ST) { |
644 | ++I; |
645 | } |
646 | #pragma omp target |
647 | #pragma omp teams |
648 | // expected-note@+3 {{loop step is expected to be positive due to this condition}} |
649 | // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} |
650 | #pragma omp distribute parallel for simd |
651 | for (IT I = begin; I <= end; I += ST) { |
652 | ++I; |
653 | } |
654 | #pragma omp target |
655 | #pragma omp teams |
656 | #pragma omp distribute parallel for simd |
657 | for (IT I = begin; I < end; ++I) { |
658 | ++I; |
659 | } |
660 | } |
661 | |
662 | static IT step() { |
663 | return IT(ST); |
664 | } |
665 | }; |
666 | template <typename IT, int ST = 0> |
667 | int dotest_gt(IT begin, IT end) { |
668 | #pragma omp target |
669 | #pragma omp teams |
670 | // expected-note@+3 2 {{loop step is expected to be negative due to this condition}} |
671 | // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
672 | #pragma omp distribute parallel for simd |
673 | for (IT I = begin; I >= end; I = I + ST) { |
674 | ++I; |
675 | } |
676 | #pragma omp target |
677 | #pragma omp teams |
678 | // expected-note@+3 2 {{loop step is expected to be negative due to this condition}} |
679 | // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
680 | #pragma omp distribute parallel for simd |
681 | for (IT I = begin; I >= end; I += ST) { |
682 | ++I; |
683 | } |
684 | |
685 | #pragma omp target |
686 | #pragma omp teams |
687 | // expected-note@+3 {{loop step is expected to be negative due to this condition}} |
688 | // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} |
689 | #pragma omp distribute parallel for simd |
690 | for (IT I = begin; I >= end; ++I) { |
691 | ++I; |
692 | } |
693 | |
694 | #pragma omp distribute parallel for simd |
695 | for (IT I = begin; I < end; I += TC<int, ST>::step()) { |
696 | ++I; |
697 | } |
698 | } |
699 | |
700 | void test_with_template() { |
701 | GoodIter begin, end; |
702 | TC<GoodIter, 100> t1; |
703 | TC<GoodIter, -100> t2; |
704 | t1.dotest_lt(begin, end); |
705 | t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} |
706 | dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} |
707 | dotest_gt<unsigned, 10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, 10>' requested here}} |
708 | } |
709 | |
710 | void test_loop_break() { |
711 | const int N = 100; |
712 | float a[N], b[N], c[N]; |
713 | #pragma omp target |
714 | #pragma omp teams |
715 | #pragma omp distribute parallel for simd |
716 | for (int i = 0; i < 10; i++) { |
717 | c[i] = a[i] + b[i]; |
718 | for (int j = 0; j < 10; ++j) { |
719 | if (a[i] > b[j]) |
720 | break; // OK in nested loop |
721 | } |
722 | switch (i) { |
723 | case 1: |
724 | b[i]++; |
725 | break; |
726 | default: |
727 | break; |
728 | } |
729 | if (c[i] > 10) |
730 | break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} |
731 | |
732 | if (c[i] > 11) |
733 | break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} |
734 | } |
735 | |
736 | #pragma omp target |
737 | #pragma omp teams |
738 | #pragma omp distribute parallel for simd |
739 | for (int i = 0; i < 10; i++) { |
740 | for (int j = 0; j < 10; j++) { |
741 | c[i] = a[i] + b[i]; |
742 | if (c[i] > 10) { |
743 | if (c[i] < 20) { |
744 | break; // OK |
745 | } |
746 | } |
747 | } |
748 | } |
749 | } |
750 | |
751 | void test_loop_eh() { |
752 | const int N = 100; |
753 | float a[N], b[N], c[N]; |
754 | #pragma omp target |
755 | #pragma omp teams |
756 | #pragma omp distribute parallel for simd |
757 | for (int i = 0; i < 10; i++) { |
758 | c[i] = a[i] + b[i]; |
759 | try { // expected-error {{'try' statement cannot be used in OpenMP simd region}} |
760 | for (int j = 0; j < 10; ++j) { |
761 | if (a[i] > b[j]) |
762 | throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} |
763 | } |
764 | throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} |
765 | } catch (float f) { |
766 | if (f > 0.1) |
767 | throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} |
768 | return; // expected-error {{cannot return from OpenMP region}} |
769 | } |
770 | switch (i) { |
771 | case 1: |
772 | b[i]++; |
773 | break; |
774 | default: |
775 | break; |
776 | } |
777 | for (int j = 0; j < 10; j++) { |
778 | if (c[i] > 10) |
779 | throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} |
780 | } |
781 | } |
782 | if (c[9] > 10) |
783 | throw c[9]; // OK |
784 | |
785 | #pragma omp distribute parallel for simd |
786 | for (int i = 0; i < 10; ++i) { |
787 | struct S { |
788 | void g() { throw 0; } |
789 | }; |
790 | } |
791 | } |
792 | |
793 | void test_loop_firstprivate_lastprivate() { |
794 | S s(4); |
795 | // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} |
796 | #pragma omp target |
797 | #pragma omp teams |
798 | #pragma omp distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} |
799 | for (int i = 0; i < 16; ++i) |
800 | ; |
801 | } |
802 | |
803 | void test_ordered() { |
804 | #pragma omp target |
805 | #pragma omp teams |
806 | #pragma omp distribute parallel for simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp distribute parallel for simd'}} |
807 | for (int i = 0; i < 16; ++i) |
808 | ; |
809 | } |
810 | |
811 | void test_nowait() { |
812 | #pragma omp target |
813 | #pragma omp teams |
814 | // expected-error@+1 2 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}} |
815 | #pragma omp distribute parallel for simd nowait nowait // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'nowait' clause}} |
816 | for (int i = 0; i < 16; ++i) |
817 | ; |
818 | } |
819 | |
820 | |