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