Clang Project

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