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