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