Home | History | Annotate | Download | only in OpenMP
      1 // RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
      2 
      3 static int sii;
      4 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
      5 static int globalii;
      6 
      7 int 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}}
    231   // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be private, predetermined as linear}}
    232   #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}}
    238   // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be shared, predetermined as linear}}
    239   #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 
    247   #pragma omp simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}}
    248   for (ii = 0; ii < 10; ii++)
    249   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];
    251 
    252 
    253   #pragma omp parallel
    254   {
    255     // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be threadprivate or thread local, predetermined as linear}}
    256     #pragma omp simd
    257     for (sii = 0; sii < 10; sii+=1)
    258       c[sii] = a[sii];
    259   }
    260 
    261   #pragma omp parallel
    262   {
    263     // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as linear}}
    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 // expected-error@+3 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}}
    272 #pragma omp simd collapse(2)
    273     for (ii = 0; ii < 10; ii += 1)
    274     for (globalii = 0; globalii < 10; globalii += 1)
    275       c[globalii] += a[globalii] + ii;
    276   }
    277 
    278   // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
    279   #pragma omp simd
    280   for (auto &item : a) {
    281     item = item + 1;
    282   }
    283 
    284   // expected-note@+3 {{loop step is expected to be positive due to this condition}}
    285   // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
    286   #pragma omp simd
    287   for (unsigned i = 9; i < 10; i--) {
    288     c[i] = a[i] + b[i];
    289   }
    290 
    291   int (*lb)[4] = nullptr;
    292   #pragma omp simd
    293   for (int (*p)[4] = lb; p < lb + 8; ++p) {
    294   }
    295 
    296   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    297   #pragma omp simd
    298   for (int a{0}; a<10; ++a) {
    299   }
    300 
    301   return 0;
    302 }
    303 
    304 // Iterators allowed in openmp for-loops.
    305 namespace std {
    306 struct random_access_iterator_tag { };
    307 template <class Iter> struct iterator_traits {
    308   typedef typename Iter::difference_type difference_type;
    309   typedef typename Iter::iterator_category iterator_category;
    310 };
    311 template <class Iter>
    312 typename iterator_traits<Iter>::difference_type
    313 distance(Iter first, Iter last) { return first - last; }
    314 }
    315 class Iter0 {
    316   public:
    317     Iter0() { }
    318     Iter0(const Iter0 &) { }
    319     Iter0 operator ++() { return *this; }
    320     Iter0 operator --() { return *this; }
    321     Iter0 operator + (int delta) { return *this; }
    322     bool operator <(Iter0 a) { return true; }
    323 };
    324 // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
    325 int operator -(Iter0 a, Iter0 b) { return 0; }
    326 class Iter1 {
    327   public:
    328     Iter1(float f=0.0f, double d=0.0) { }
    329     Iter1(const Iter1 &) { }
    330     Iter1 operator ++() { return *this; }
    331     Iter1 operator --() { return *this; }
    332     bool operator <(Iter1 a) { return true; }
    333     bool operator >=(Iter1 a) { return false; }
    334 };
    335 class GoodIter {
    336   public:
    337     GoodIter() { }
    338     GoodIter(const GoodIter &) { }
    339     GoodIter(int fst, int snd) { }
    340     GoodIter &operator =(const GoodIter &that) { return *this; }
    341     GoodIter &operator =(const Iter0 &that) { return *this; }
    342     GoodIter &operator +=(int x) { return *this; }
    343     explicit GoodIter(void *) { }
    344     GoodIter operator ++() { return *this; }
    345     GoodIter operator --() { return *this; }
    346     bool operator !() { return true; }
    347     bool operator <(GoodIter a) { return true; }
    348     bool operator <=(GoodIter a) { return true; }
    349     bool operator >=(GoodIter a) { return false; }
    350     typedef int difference_type;
    351     typedef std::random_access_iterator_tag iterator_category;
    352 };
    353 // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
    354 int operator -(GoodIter a, GoodIter b) { return 0; }
    355 // expected-note@+1 2 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
    356 GoodIter operator -(GoodIter a) { return a; }
    357 // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
    358 GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
    359 GoodIter operator +(GoodIter a, int v) { return GoodIter(); }
    360 // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
    361 GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
    362 GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
    363 
    364 int test_with_random_access_iterator() {
    365   GoodIter begin, end;
    366   Iter0 begin0, end0;
    367   #pragma omp simd
    368   for (GoodIter I = begin; I < end; ++I)
    369     ++I;
    370   // expected-error@+2 {{variable must be of integer or random access iterator type}}
    371   #pragma omp simd
    372   for (GoodIter &I = begin; I < end; ++I)
    373     ++I;
    374   #pragma omp simd
    375   for (GoodIter I = begin; I >= end; --I)
    376     ++I;
    377   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    378   #pragma omp simd
    379   for (GoodIter I(begin); I < end; ++I)
    380     ++I;
    381   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    382   #pragma omp simd
    383   for (GoodIter I(nullptr); I < end; ++I)
    384     ++I;
    385   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    386   #pragma omp simd
    387   for (GoodIter I(0); I < end; ++I)
    388     ++I;
    389   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    390   #pragma omp simd
    391   for (GoodIter I(1,2); I < end; ++I)
    392     ++I;
    393   #pragma omp simd
    394   for (begin = GoodIter(0); begin < end; ++begin)
    395     ++begin;
    396   #pragma omp simd
    397   for (begin = GoodIter(1,2); begin < end; ++begin)
    398     ++begin;
    399   // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
    400   #pragma omp simd
    401   for (++begin; begin < end; ++begin)
    402     ++begin;
    403   #pragma omp simd
    404   for (begin = end; begin < end; ++begin)
    405     ++begin;
    406   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
    407   #pragma omp simd
    408   for (GoodIter I = begin; I - I; ++I)
    409     ++I;
    410   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
    411   #pragma omp simd
    412   for (GoodIter I = begin; begin < end; ++I)
    413     ++I;
    414   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
    415   #pragma omp simd
    416   for (GoodIter I = begin; !I; ++I)
    417     ++I;
    418   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
    419   // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    420   #pragma omp simd
    421   for (GoodIter I = begin; I >= end; I = I + 1)
    422     ++I;
    423   #pragma omp simd
    424   for (GoodIter I = begin; I >= end; I = I - 1)
    425     ++I;
    426   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
    427   #pragma omp simd
    428   for (GoodIter I = begin; I >= end; I = -I)
    429     ++I;
    430   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
    431   // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    432   #pragma omp simd
    433   for (GoodIter I = begin; I >= end; I = 2 + I)
    434     ++I;
    435   // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
    436   #pragma omp simd
    437   for (GoodIter I = begin; I >= end; I = 2 - I)
    438     ++I;
    439   #pragma omp simd
    440   for (Iter0 I = begin0; I < end0; ++I)
    441     ++I;
    442 
    443   // Initializer is constructor without params.
    444   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    445   #pragma omp simd
    446   for (Iter0 I; I < end0; ++I)
    447     ++I;
    448 
    449   Iter1 begin1, end1;
    450   // expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
    451   // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
    452   #pragma omp simd
    453   for (Iter1 I = begin1; I < end1; ++I)
    454     ++I;
    455   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
    456   // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    457   #pragma omp simd
    458   for (Iter1 I = begin1; I >= end1; ++I)
    459     ++I;
    460 
    461   // Initializer is constructor with all default params.
    462   // expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
    463   // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
    464   // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
    465   #pragma omp simd
    466   for (Iter1 I; I < end1; ++I) {
    467   }
    468 
    469   return 0;
    470 }
    471 
    472 template <typename IT, int ST> class TC {
    473   public:
    474     int dotest_lt(IT begin, IT end) {
    475       // expected-note@+3 {{loop step is expected to be positive due to this condition}}
    476       // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
    477       #pragma omp simd
    478       for (IT I = begin; I < end; I = I + ST) {
    479         ++I;
    480       }
    481       // expected-note@+3 {{loop step is expected to be positive due to this condition}}
    482       // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
    483       #pragma omp simd
    484       for (IT I = begin; I <= end; I += ST) {
    485         ++I;
    486       }
    487       #pragma omp simd
    488       for (IT I = begin; I < end; ++I) {
    489         ++I;
    490       }
    491     }
    492 
    493     static IT step() {
    494       return IT(ST);
    495     }
    496 };
    497 template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) {
    498   // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
    499   // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    500   #pragma omp simd
    501   for (IT I = begin; I >= end; I = I + ST) {
    502     ++I;
    503   }
    504   // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
    505   // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    506   #pragma omp simd
    507   for (IT I = begin; I >= end; I += ST) {
    508     ++I;
    509   }
    510 
    511   // expected-note@+3 {{loop step is expected to be negative due to this condition}}
    512   // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
    513   #pragma omp simd
    514   for (IT I = begin; I >= end; ++I) {
    515     ++I;
    516   }
    517 
    518   #pragma omp simd
    519   for (IT I = begin; I < end; I+=TC<int,ST>::step()) {
    520     ++I;
    521   }
    522 }
    523 
    524 void test_with_template() {
    525   GoodIter begin, end;
    526   TC<GoodIter, 100> t1;
    527   TC<GoodIter, -100> t2;
    528   t1.dotest_lt(begin, end);
    529   t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
    530   dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
    531   dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
    532 }
    533 
    534 void test_loop_break() {
    535   const int N = 100;
    536   float a[N], b[N], c[N];
    537   #pragma omp simd
    538   for (int i = 0; i < 10; i++) {
    539     c[i] = a[i] + b[i];
    540     for (int j = 0; j < 10; ++j) {
    541       if (a[i] > b[j])
    542         break; // OK in nested loop
    543     }
    544     switch(i) {
    545       case 1:
    546         b[i]++;
    547         break;
    548       default:
    549         break;
    550     }
    551     if (c[i] > 10)
    552       break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
    553 
    554     if (c[i] > 11)
    555       break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
    556   }
    557 
    558   #pragma omp simd
    559   for (int i = 0; i < 10; i++) {
    560     for (int j = 0; j < 10; j++) {
    561       c[i] = a[i] + b[i];
    562       if (c[i] > 10) {
    563         if (c[i] < 20) {
    564           break; // OK
    565         }
    566       }
    567     }
    568   }
    569 }
    570 
    571 void test_loop_eh() {
    572   const int N = 100;
    573   float a[N], b[N], c[N];
    574   #pragma omp simd
    575   for (int i = 0; i < 10; i++) {
    576     c[i] = a[i] + b[i];
    577     try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
    578       for (int j = 0; j < 10; ++j) {
    579         if (a[i] > b[j])
    580           throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
    581       }
    582       throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
    583     }
    584     catch (float f) {
    585       if (f > 0.1)
    586         throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
    587       return; // expected-error {{cannot return from OpenMP region}}
    588     }
    589     switch(i) {
    590       case 1:
    591         b[i]++;
    592         break;
    593       default:
    594         break;
    595     }
    596     for (int j = 0; j < 10; j++) {
    597       if (c[i] > 10)
    598         throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
    599     }
    600   }
    601   if (c[9] > 10)
    602     throw c[9]; // OK
    603 
    604   #pragma omp simd
    605   for (int i = 0; i < 10; ++i) {
    606     struct S {
    607       void g() { throw 0; }
    608     };
    609   }
    610 }
    611 
    612