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