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