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