]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / OpenMP / distribute_parallel_for_simd_loop_messages.cpp
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 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 #pragma omp target
148 #pragma omp teams
149 // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
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