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