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