Clang Project

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