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