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