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