Clang Project

clang_source_code/test/OpenMP/distribute_simd_loop_messages.cpp
1// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
2
3// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
4
5static int sii;
6// expected-note@+1 {{defined as threadprivate or thread local}}
7#pragma omp threadprivate(sii)
8static int globalii;
9
10int 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  // Ok
139  #pragma omp target
140  #pragma omp teams
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.
410namespace std {
411struct random_access_iterator_tag { };
412template <class Iter> struct iterator_traits {
413  typedef typename Iter::difference_type difference_type;
414  typedef typename Iter::iterator_category iterator_category;
415};
416template <class Iter>
417typename iterator_traits<Iter>::difference_type
418distance(Iter first, Iter last) { return first - last; }
419}
420class 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}}
430int operator -(Iter0 a, Iter0 b) { return 0; }
431class 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};
440class 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}}
459int 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}}
461GoodIter operator -(GoodIter a) { return a; }
462// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
463GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
464GoodIter 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}}
466GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
467GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
468
469int 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) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning {{Non-trivial type 'GoodIter' is mapped, only trivial types are 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(1,2); I < end; ++I) // expected-warning {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
511    ++I;
512  #pragma omp target
513  #pragma omp teams
514  #pragma omp distribute simd
515  for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
516    ++begin;
517  #pragma omp target
518  #pragma omp teams
519  #pragma omp distribute simd
520  for (begin = GoodIter(1,2); begin < end; ++begin) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning 2 {{Non-trivial type 'Iter0' is mapped, only trivial types are guaranteed to be mapped correctly}}
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) // expected-warning {{Non-trivial type 'Iter0' is mapped, only trivial types are guaranteed to be mapped correctly}}
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
625template <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) { // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
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};
652template <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()) { // expected-warning 2 {{Non-trivial type 'GoodIter' is mapped, only trivial types are guaranteed to be mapped correctly}}
683    ++I;
684  }
685}
686
687void test_with_template() {
688  GoodIter begin, end;
689  TC<GoodIter, 100> t1;
690  TC<GoodIter, -100> t2;
691  t1.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, 100>::dotest_lt' requested here}}
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
697void 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
738void 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