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