• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
2 
3 static int sii;
4 // expected-note@+1 {{defined as threadprivate or thread local}}
5 #pragma omp threadprivate(sii)
6 static int globalii;
7 
test_iteration_spaces()8 int test_iteration_spaces() {
9   const int N = 100;
10   float a[N], b[N], c[N];
11   int ii, jj, kk;
12   float fii;
13   double dii;
14   #pragma omp target
15   #pragma omp teams
16   #pragma omp distribute simd
17   for (int i = 0; i < 10; i+=1) {
18     c[i] = a[i] + b[i];
19   }
20   #pragma omp target
21   #pragma omp teams
22   #pragma omp distribute simd
23   for (char i = 0; i < 10; i++) {
24     c[i] = a[i] + b[i];
25   }
26   #pragma omp target
27   #pragma omp teams
28   #pragma omp distribute simd
29   for (char i = 0; i < 10; i+='\1') {
30     c[i] = a[i] + b[i];
31   }
32   #pragma omp target
33   #pragma omp teams
34   #pragma omp distribute simd
35   for (long long i = 0; i < 10; i++) {
36     c[i] = a[i] + b[i];
37   }
38   #pragma omp target
39   #pragma omp teams
40   // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
41   #pragma omp distribute simd
42   for (long long i = 0; i < 10; i+=1.5) {
43     c[i] = a[i] + b[i];
44   }
45   #pragma omp target
46   #pragma omp teams
47   #pragma omp distribute simd
48   for (long long i = 0; i < 'z'; i+=1u) {
49     c[i] = a[i] + b[i];
50   }
51   #pragma omp target
52   #pragma omp teams
53   // expected-error@+2 {{variable must be of integer or random access iterator type}}
54   #pragma omp distribute simd
55   for (float fi = 0; fi < 10.0; fi++) {
56     c[(int)fi] = a[(int)fi] + b[(int)fi];
57   }
58   #pragma omp target
59   #pragma omp teams
60   // expected-error@+2 {{variable must be of integer or random access iterator type}}
61   #pragma omp distribute simd
62   for (double fi = 0; fi < 10.0; fi++) {
63     c[(int)fi] = a[(int)fi] + b[(int)fi];
64   }
65   #pragma omp target
66   #pragma omp teams
67   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
68   #pragma omp distribute simd
69   for (int &ref = ii; ref < 10; ref++) {
70   }
71   #pragma omp target
72   #pragma omp teams
73   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
74   #pragma omp distribute simd
75   for (int i; i < 10; i++)
76     c[i] = a[i];
77 
78   #pragma omp target
79   #pragma omp teams
80   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
81   #pragma omp distribute simd
82   for (int i = 0, j = 0; i < 10; ++i)
83     c[i] = a[i];
84 
85   #pragma omp target
86   #pragma omp teams
87   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
88   #pragma omp distribute simd
89   for (;ii < 10; ++ii)
90     c[ii] = a[ii];
91 
92   #pragma omp target
93   #pragma omp teams
94   // expected-warning@+3 {{expression result unused}}
95   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
96   #pragma omp distribute simd
97   for (ii + 1;ii < 10; ++ii)
98     c[ii] = a[ii];
99 
100   #pragma omp target
101   #pragma omp teams
102   // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
103   #pragma omp distribute simd
104   for (c[ii] = 0;ii < 10; ++ii)
105     c[ii] = a[ii];
106 
107   // Ok to skip parenthesises.
108   #pragma omp target
109   #pragma omp teams
110   #pragma omp distribute simd
111   for (((ii)) = 0;ii < 10; ++ii)
112     c[ii] = a[ii];
113 
114   #pragma omp target
115   #pragma omp teams
116   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
117   #pragma omp distribute simd
118   for (int i = 0; i; i++)
119     c[i] = a[i];
120 
121   #pragma omp target
122   #pragma omp teams
123   // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
124   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
125   #pragma omp distribute simd
126   for (int i = 0; jj < kk; ii++)
127     c[i] = a[i];
128 
129   #pragma omp target
130   #pragma omp teams
131   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
132   #pragma omp distribute simd
133   for (int i = 0; !!i; i++)
134     c[i] = a[i];
135 
136   #pragma omp target
137   #pragma omp teams
138   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
139   #pragma omp distribute simd
140   for (int i = 0; i != 1; i++)
141     c[i] = a[i];
142 
143   #pragma omp target
144   #pragma omp teams
145   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
146   #pragma omp distribute simd
147   for (int i = 0; ; i++)
148     c[i] = a[i];
149 
150   // Ok.
151   #pragma omp target
152   #pragma omp teams
153   #pragma omp distribute simd
154   for (int i = 11; i > 10; i--)
155     c[i] = a[i];
156 
157   // Ok.
158   #pragma omp target
159   #pragma omp teams
160   #pragma omp distribute simd
161   for (int i = 0; i < 10; ++i)
162     c[i] = a[i];
163 
164     // Ok.
165   #pragma omp target
166   #pragma omp teams
167   #pragma omp distribute simd
168   for (ii = 0; ii < 10; ++ii)
169     c[ii] = a[ii];
170 
171   #pragma omp target
172   #pragma omp teams
173   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
174   #pragma omp distribute simd
175   for (ii = 0; ii < 10; ++jj)
176     c[ii] = a[jj];
177 
178   #pragma omp target
179   #pragma omp teams
180   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
181   #pragma omp distribute simd
182   for (ii = 0; ii < 10; ++ ++ ii)
183     c[ii] = a[ii];
184 
185   // Ok but undefined behavior (in general, cannot check that incr
186   // is really loop-invariant).
187   #pragma omp target
188   #pragma omp teams
189   #pragma omp distribute simd
190   for (ii = 0; ii < 10; ii = ii + ii)
191     c[ii] = a[ii];
192 
193   #pragma omp target
194   #pragma omp teams
195   // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
196   #pragma omp distribute simd
197   for (ii = 0; ii < 10; ii = ii + 1.0f)
198     c[ii] = a[ii];
199 
200   // Ok - step was converted to integer type.
201   #pragma omp target
202   #pragma omp teams
203   #pragma omp distribute simd
204   for (ii = 0; ii < 10; ii = ii + (int)1.1f)
205     c[ii] = a[ii];
206 
207   #pragma omp target
208   #pragma omp teams
209   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
210   #pragma omp distribute simd
211   for (ii = 0; ii < 10; jj = ii + 2)
212     c[ii] = a[ii];
213 
214   #pragma omp target
215   #pragma omp teams
216   // expected-warning@+3 {{relational comparison result unused}}
217   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
218   #pragma omp distribute simd
219   for (ii = 0; ii < 10; jj > kk + 2)
220     c[ii] = a[ii];
221 
222   #pragma omp target
223   #pragma omp teams
224   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
225   #pragma omp distribute simd
226   for (ii = 0; ii < 10;)
227     c[ii] = a[ii];
228 
229   #pragma omp target
230   #pragma omp teams
231   // expected-warning@+3 {{expression result unused}}
232   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
233   #pragma omp distribute simd
234   for (ii = 0; ii < 10; !ii)
235     c[ii] = a[ii];
236 
237   #pragma omp target
238   #pragma omp teams
239   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
240   #pragma omp distribute simd
241   for (ii = 0; ii < 10; ii ? ++ii : ++jj)
242     c[ii] = a[ii];
243 
244   #pragma omp target
245   #pragma omp teams
246   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
247   #pragma omp distribute simd
248   for (ii = 0; ii < 10; ii = ii < 10)
249     c[ii] = a[ii];
250 
251   #pragma omp target
252   #pragma omp teams
253   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
254   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
255   #pragma omp distribute simd
256   for (ii = 0; ii < 10; ii = ii + 0)
257     c[ii] = a[ii];
258 
259   #pragma omp target
260   #pragma omp teams
261   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
262   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
263   #pragma omp distribute simd
264   for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
265     c[ii] = a[ii];
266 
267   #pragma omp target
268   #pragma omp teams
269   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
270   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
271   #pragma omp distribute simd
272   for (ii = 0; (ii) < 10; ii-=25)
273     c[ii] = a[ii];
274 
275   #pragma omp target
276   #pragma omp teams
277   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
278   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
279   #pragma omp distribute simd
280   for (ii = 0; (ii < 10); ii-=0)
281     c[ii] = a[ii];
282 
283   #pragma omp target
284   #pragma omp teams
285   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
286   // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
287   #pragma omp distribute simd
288   for (ii = 0; ii > 10; (ii+=0))
289     c[ii] = a[ii];
290 
291   #pragma omp target
292   #pragma omp teams
293   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
294   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
295   #pragma omp distribute simd
296   for (ii = 0; ii < 10; (ii) = (1-1)+(ii))
297     c[ii] = a[ii];
298 
299   #pragma omp target
300   #pragma omp teams
301   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
302   // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
303   #pragma omp distribute simd
304   for ((ii = 0); ii > 10; (ii-=0))
305     c[ii] = a[ii];
306 
307   #pragma omp target
308   #pragma omp teams
309   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
310   // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
311   #pragma omp distribute simd
312   for (ii = 0; (ii < 10); (ii-=0))
313     c[ii] = a[ii];
314 
315   #pragma omp target
316   #pragma omp teams
317   // expected-note@+2  {{defined as private}}
318   // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be private, predetermined as linear}}
319   #pragma omp distribute simd private(ii)
320   for (ii = 0; ii < 10; ii++)
321     c[ii] = a[ii];
322 
323   #pragma omp target
324   #pragma omp teams
325   // expected-error@+3 {{unexpected OpenMP clause 'shared' in directive '#pragma omp distribute simd'}}
326   // expected-note@+2  {{defined as shared}}
327   // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be shared, predetermined as linear}}
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
distance(Iter first,Iter last)418 distance(Iter first, Iter last) { return first - last; }
419 }
420 class Iter0 {
421   public:
Iter0()422     Iter0() { }
Iter0(const Iter0 &)423     Iter0(const Iter0 &) { }
operator ++()424     Iter0 operator ++() { return *this; }
operator --()425     Iter0 operator --() { return *this; }
operator +(int delta)426     Iter0 operator + (int delta) { return *this; }
operator <(Iter0 a)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}}
operator -(Iter0 a,Iter0 b)430 int operator -(Iter0 a, Iter0 b) { return 0; }
431 class Iter1 {
432   public:
Iter1(float f=0.0f,double d=0.0)433     Iter1(float f=0.0f, double d=0.0) { }
Iter1(const Iter1 &)434     Iter1(const Iter1 &) { }
operator ++()435     Iter1 operator ++() { return *this; }
operator --()436     Iter1 operator --() { return *this; }
operator <(Iter1 a)437     bool operator <(Iter1 a) { return true; }
operator >=(Iter1 a)438     bool operator >=(Iter1 a) { return false; }
439 };
440 class GoodIter {
441   public:
GoodIter()442     GoodIter() { }
GoodIter(const GoodIter &)443     GoodIter(const GoodIter &) { }
GoodIter(int fst,int snd)444     GoodIter(int fst, int snd) { }
operator =(const GoodIter & that)445     GoodIter &operator =(const GoodIter &that) { return *this; }
operator =(const Iter0 & that)446     GoodIter &operator =(const Iter0 &that) { return *this; }
operator +=(int x)447     GoodIter &operator +=(int x) { return *this; }
GoodIter(void *)448     explicit GoodIter(void *) { }
operator ++()449     GoodIter operator ++() { return *this; }
operator --()450     GoodIter operator --() { return *this; }
operator !()451     bool operator !() { return true; }
operator <(GoodIter a)452     bool operator <(GoodIter a) { return true; }
operator <=(GoodIter a)453     bool operator <=(GoodIter a) { return true; }
operator >=(GoodIter a)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}}
operator -(GoodIter a,GoodIter b)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}}
operator -(GoodIter a)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}}
operator -(GoodIter a,int v)463 GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
operator +(GoodIter a,int v)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}}
operator -(int v,GoodIter a)466 GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
operator +(int v,GoodIter a)467 GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
468 
test_with_random_access_iterator()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:
dotest_lt(IT begin,IT end)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 
step()648     static IT step() {
649       return IT(ST);
650     }
651 };
dotest_gt(IT begin,IT end)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 
test_with_template()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 
test_loop_break()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 
test_loop_eh()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