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