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