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