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