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