Home | History | Annotate | Download | only in OpenMP
      1 // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
      2 
      3 int foo() {
      4 L1:
      5   foo();
      6 #pragma omp atomic
      7   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
      8   // expected-note@+1 {{expected an expression statement}}
      9   {
     10     foo();
     11     goto L1; // expected-error {{use of undeclared label 'L1'}}
     12   }
     13   goto L2; // expected-error {{use of undeclared label 'L2'}}
     14 #pragma omp atomic
     15   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
     16   // expected-note@+1 {{expected an expression statement}}
     17   {
     18     foo();
     19   L2:
     20     foo();
     21   }
     22 
     23   return 0;
     24 }
     25 
     26 struct S {
     27   int a;
     28   S &operator=(int v) {
     29     a = v;
     30     return *this;
     31   }
     32   S &operator+=(const S &s) {
     33     a += s.a;
     34     return *this;
     35   }
     36 };
     37 
     38 template <class T>
     39 T read() {
     40   T a = T(), b = T();
     41 // Test for atomic read
     42 #pragma omp atomic read
     43   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     44   // expected-note@+1 {{expected an expression statement}}
     45   ;
     46 #pragma omp atomic read
     47   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     48   // expected-note@+1 {{expected built-in assignment operator}}
     49   foo();
     50 #pragma omp atomic read
     51   // expected-error@+2 2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     52   // expected-note@+1 2 {{expected built-in assignment operator}}
     53   a += b;
     54 #pragma omp atomic read
     55   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     56   // expected-note@+1 {{expected lvalue expression}}
     57   a = 0;
     58 #pragma omp atomic read
     59   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     60   // expected-note@+1 {{expected built-in assignment operator}}
     61   a = b;
     62   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
     63 #pragma omp atomic read read
     64   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     65   // expected-note@+1 {{expected built-in assignment operator}}
     66   a = b;
     67 
     68   return a;
     69 }
     70 
     71 int read() {
     72   int a = 0, b = 0;
     73 // Test for atomic read
     74 #pragma omp atomic read
     75   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     76   // expected-note@+1 {{expected an expression statement}}
     77   ;
     78 #pragma omp atomic read
     79   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     80   // expected-note@+1 {{expected built-in assignment operator}}
     81   foo();
     82 #pragma omp atomic read
     83   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     84   // expected-note@+1 {{expected built-in assignment operator}}
     85   a += b;
     86 #pragma omp atomic read
     87   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
     88   // expected-note@+1 {{expected lvalue expression}}
     89   a = 0;
     90 #pragma omp atomic read
     91   a = b;
     92   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
     93 #pragma omp atomic read read
     94   a = b;
     95 
     96   // expected-note@+2 {{in instantiation of function template specialization 'read<S>' requested here}}
     97   // expected-note@+1 {{in instantiation of function template specialization 'read<int>' requested here}}
     98   return read<int>() + read<S>().a;
     99 }
    100 
    101 template <class T>
    102 T write() {
    103   T a, b = 0;
    104 // Test for atomic write
    105 #pragma omp atomic write
    106   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    107   // expected-note@+1 {{expected an expression statement}}
    108   ;
    109 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
    110 #pragma omp atomic write write
    111   a = b;
    112 #pragma omp atomic write
    113   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    114   // expected-note@+1 {{expected built-in assignment operator}}
    115   foo();
    116 #pragma omp atomic write
    117   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    118   // expected-note@+1 {{expected built-in assignment operator}}
    119   a += b;
    120 #pragma omp atomic write
    121   a = 0;
    122 #pragma omp atomic write
    123   a = b;
    124 
    125   return T();
    126 }
    127 
    128 int write() {
    129   int a, b = 0;
    130 // Test for atomic write
    131 #pragma omp atomic write
    132   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    133   // expected-note@+1 {{expected an expression statement}}
    134   ;
    135 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
    136 #pragma omp atomic write write
    137   a = b;
    138 #pragma omp atomic write
    139   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    140   // expected-note@+1 {{expected built-in assignment operator}}
    141   foo();
    142 #pragma omp atomic write
    143   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
    144   // expected-note@+1 {{expected built-in assignment operator}}
    145   a += b;
    146 #pragma omp atomic write
    147   a = 0;
    148 #pragma omp atomic write
    149   a = foo();
    150 
    151   // expected-note@+1 {{in instantiation of function template specialization 'write<int>' requested here}}
    152   return write<int>();
    153 }
    154 
    155 template <class T>
    156 T update() {
    157   T a = 0, b = 0, c = 0;
    158 // Test for atomic update
    159 #pragma omp atomic update
    160   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    161   // expected-note@+1 {{expected an expression statement}}
    162   ;
    163 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
    164 #pragma omp atomic update update
    165   a += b;
    166 #pragma omp atomic
    167   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    168   // expected-note@+1 {{expected built-in binary operator}}
    169   a = b;
    170 #pragma omp atomic update
    171   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    172   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    173   a = b || a;
    174 #pragma omp atomic update
    175   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    176   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    177   a = a && b;
    178 #pragma omp atomic update
    179   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    180   // expected-note@+1 {{expected in right hand side of expression}}
    181   a = float(a) + b;
    182 #pragma omp atomic
    183   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    184   // expected-note@+1 {{expected in right hand side of expression}}
    185   a = 2 * b;
    186 #pragma omp atomic
    187   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    188   // expected-note@+1 {{expected in right hand side of expression}}
    189   a = b + *&a;
    190 #pragma omp atomic
    191   *&a = b * *&a;
    192 #pragma omp atomic update
    193   a++;
    194 #pragma omp atomic
    195   ++a;
    196 #pragma omp atomic update
    197   a--;
    198 #pragma omp atomic
    199   --a;
    200 #pragma omp atomic update
    201   a += b;
    202 #pragma omp atomic
    203   a %= b;
    204 #pragma omp atomic update
    205   a *= b;
    206 #pragma omp atomic
    207   a -= b;
    208 #pragma omp atomic update
    209   a /= b;
    210 #pragma omp atomic
    211   a &= b;
    212 #pragma omp atomic update
    213   a ^= b;
    214 #pragma omp atomic
    215   a |= b;
    216 #pragma omp atomic update
    217   a <<= b;
    218 #pragma omp atomic
    219   a >>= b;
    220 #pragma omp atomic update
    221   a = b + a;
    222 #pragma omp atomic
    223   a = a * b;
    224 #pragma omp atomic update
    225   a = b - a;
    226 #pragma omp atomic
    227   a = a / b;
    228 #pragma omp atomic update
    229   a = b & a;
    230 #pragma omp atomic
    231   a = a ^ b;
    232 #pragma omp atomic update
    233   a = b | a;
    234 #pragma omp atomic
    235   a = a << b;
    236 #pragma omp atomic
    237   a = b >> a;
    238 
    239 #pragma omp atomic
    240   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    241   // expected-note@+1 {{expected an expression statement}}
    242   ;
    243 
    244   return T();
    245 }
    246 
    247 int update() {
    248   int a, b = 0;
    249 // Test for atomic update
    250 #pragma omp atomic update
    251   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    252   // expected-note@+1 {{expected an expression statement}}
    253   ;
    254 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
    255 #pragma omp atomic update update
    256   a += b;
    257 #pragma omp atomic
    258   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    259   // expected-note@+1 {{expected built-in binary operator}}
    260   a = b;
    261 #pragma omp atomic update
    262   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    263   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    264   a = b || a;
    265 #pragma omp atomic update
    266   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    267   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    268   a = a && b;
    269 #pragma omp atomic update
    270   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    271   // expected-note@+1 {{expected in right hand side of expression}}
    272   a = float(a) + b;
    273 #pragma omp atomic
    274   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    275   // expected-note@+1 {{expected in right hand side of expression}}
    276   a = 2 * b;
    277 #pragma omp atomic
    278   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    279   // expected-note@+1 {{expected in right hand side of expression}}
    280   a = b + *&a;
    281 #pragma omp atomic update
    282   a++;
    283 #pragma omp atomic
    284   ++a;
    285 #pragma omp atomic update
    286   a--;
    287 #pragma omp atomic
    288   --a;
    289 #pragma omp atomic update
    290   a += b;
    291 #pragma omp atomic
    292   a %= b;
    293 #pragma omp atomic update
    294   a *= b;
    295 #pragma omp atomic
    296   a -= b;
    297 #pragma omp atomic update
    298   a /= b;
    299 #pragma omp atomic
    300   a &= b;
    301 #pragma omp atomic update
    302   a ^= b;
    303 #pragma omp atomic
    304   a |= b;
    305 #pragma omp atomic update
    306   a <<= b;
    307 #pragma omp atomic
    308   a >>= b;
    309 #pragma omp atomic update
    310   a = b + a;
    311 #pragma omp atomic
    312   a = a * b;
    313 #pragma omp atomic update
    314   a = b - a;
    315 #pragma omp atomic
    316   a = a / b;
    317 #pragma omp atomic update
    318   a = b & a;
    319 #pragma omp atomic
    320   a = a ^ b;
    321 #pragma omp atomic update
    322   a = b | a;
    323 #pragma omp atomic
    324   a = a << b;
    325 #pragma omp atomic
    326   a = b >> a;
    327 #pragma omp atomic
    328   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    329   // expected-note@+1 {{expected an expression statement}}
    330   ;
    331 
    332   return update<int>();
    333 }
    334 
    335 template <class T>
    336 T capture() {
    337   T a = 0, b = 0, c = 0;
    338 // Test for atomic capture
    339 #pragma omp atomic capture
    340   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    341   // expected-note@+1 {{expected compound statement}}
    342   ;
    343 #pragma omp atomic capture
    344   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    345   // expected-note@+1 {{expected assignment expression}}
    346   foo();
    347 #pragma omp atomic capture
    348   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    349   // expected-note@+1 {{expected built-in binary or unary operator}}
    350   a = b;
    351 #pragma omp atomic capture
    352   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    353   // expected-note@+1 {{expected assignment expression}}
    354   a = b || a;
    355 #pragma omp atomic capture
    356   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    357   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    358   b = a = a && b;
    359 #pragma omp atomic capture
    360   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    361   // expected-note@+1 {{expected assignment expression}}
    362   a = (float)a + b;
    363 #pragma omp atomic capture
    364   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    365   // expected-note@+1 {{expected assignment expression}}
    366   a = 2 * b;
    367 #pragma omp atomic capture
    368   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    369   // expected-note@+1 {{expected assignment expression}}
    370   a = b + *&a;
    371 #pragma omp atomic capture
    372   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    373   // expected-note@+1 {{expected exactly two expression statements}}
    374   { a = b; }
    375 #pragma omp atomic capture
    376   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    377   // expected-note@+1 {{expected exactly two expression statements}}
    378   {}
    379 #pragma omp atomic capture
    380   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    381   // expected-note@+1 {{expected in right hand side of the first expression}}
    382   {a = b;a = b;}
    383 #pragma omp atomic capture
    384   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    385   // expected-note@+1 {{expected in right hand side of the first expression}}
    386   {a = b; a = b || a;}
    387 #pragma omp atomic capture
    388   {b = a; a = a && b;}
    389 #pragma omp atomic capture
    390   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    391   // expected-note@+1 {{expected in right hand side of expression}}
    392   b = a = (float)a + b;
    393 #pragma omp atomic capture
    394   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    395   // expected-note@+1 {{expected in right hand side of expression}}
    396   b = a = 2 * b;
    397 #pragma omp atomic capture
    398   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    399   // expected-note@+1 {{expected in right hand side of expression}}
    400   b = a = b + *&a;
    401 #pragma omp atomic capture
    402   c = *&a = *&a +  2;
    403 #pragma omp atomic capture
    404   c = a++;
    405 #pragma omp atomic capture
    406   c = ++a;
    407 #pragma omp atomic capture
    408   c = a--;
    409 #pragma omp atomic capture
    410   c = --a;
    411 #pragma omp atomic capture
    412   c = a += b;
    413 #pragma omp atomic capture
    414   c = a %= b;
    415 #pragma omp atomic capture
    416   c = a *= b;
    417 #pragma omp atomic capture
    418   c = a -= b;
    419 #pragma omp atomic capture
    420   c = a /= b;
    421 #pragma omp atomic capture
    422   c = a &= b;
    423 #pragma omp atomic capture
    424   c = a ^= b;
    425 #pragma omp atomic capture
    426   c = a |= b;
    427 #pragma omp atomic capture
    428   c = a <<= b;
    429 #pragma omp atomic capture
    430   c = a >>= b;
    431 #pragma omp atomic capture
    432   c = a = b + a;
    433 #pragma omp atomic capture
    434   c = a = a * b;
    435 #pragma omp atomic capture
    436   c = a = b - a;
    437 #pragma omp atomic capture
    438   c = a = a / b;
    439 #pragma omp atomic capture
    440   c = a = b & a;
    441 #pragma omp atomic capture
    442   c = a = a ^ b;
    443 #pragma omp atomic capture
    444   c = a = b | a;
    445 #pragma omp atomic capture
    446   c = a = a << b;
    447 #pragma omp atomic capture
    448   c = a = b >> a;
    449 #pragma omp atomic capture
    450   { c = *&a; *&a = *&a +  2;}
    451 #pragma omp atomic capture
    452   { *&a = *&a +  2; c = *&a;}
    453 #pragma omp atomic capture
    454   {c = a; a++;}
    455 #pragma omp atomic capture
    456   {++a;c = a;}
    457 #pragma omp atomic capture
    458   {c = a;a--;}
    459 #pragma omp atomic capture
    460   {--a;c = a;}
    461 #pragma omp atomic capture
    462   {c = a; a += b;}
    463 #pragma omp atomic capture
    464   {a %= b; c = a;}
    465 #pragma omp atomic capture
    466   {c = a; a *= b;}
    467 #pragma omp atomic capture
    468   {a -= b;c = a;}
    469 #pragma omp atomic capture
    470   {c = a; a /= b;}
    471 #pragma omp atomic capture
    472   {a &= b; c = a;}
    473 #pragma omp atomic capture
    474   {c = a; a ^= b;}
    475 #pragma omp atomic capture
    476   {a |= b; c = a;}
    477 #pragma omp atomic capture
    478   {c = a; a <<= b;}
    479 #pragma omp atomic capture
    480   {a >>= b; c = a;}
    481 #pragma omp atomic capture
    482   {c = a; a = b + a;}
    483 #pragma omp atomic capture
    484   {a = a * b; c = a;}
    485 #pragma omp atomic capture
    486   {c = a; a = b - a;}
    487 #pragma omp atomic capture
    488   {a = a / b; c = a;}
    489 #pragma omp atomic capture
    490   {c = a; a = b & a;}
    491 #pragma omp atomic capture
    492   {a = a ^ b; c = a;}
    493 #pragma omp atomic capture
    494   {c = a; a = b | a;}
    495 #pragma omp atomic capture
    496   {a = a << b; c = a;}
    497 #pragma omp atomic capture
    498   {c = a; a = b >> a;}
    499 #pragma omp atomic capture
    500   {c = a; a = foo();}
    501   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
    502 #pragma omp atomic capture capture
    503   b = a /= b;
    504 
    505   return T();
    506 }
    507 
    508 int capture() {
    509   int a = 0, b = 0, c = 0;
    510 // Test for atomic capture
    511 #pragma omp atomic capture
    512   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    513   // expected-note@+1 {{expected compound statement}}
    514   ;
    515 #pragma omp atomic capture
    516   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    517   // expected-note@+1 {{expected assignment expression}}
    518   foo();
    519 #pragma omp atomic capture
    520   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    521   // expected-note@+1 {{expected built-in binary or unary operator}}
    522   a = b;
    523 #pragma omp atomic capture
    524   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    525   // expected-note@+1 {{expected assignment expression}}
    526   a = b || a;
    527 #pragma omp atomic capture
    528   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    529   // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}}
    530   b = a = a && b;
    531 #pragma omp atomic capture
    532   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    533   // expected-note@+1 {{expected assignment expression}}
    534   a = (float)a + b;
    535 #pragma omp atomic capture
    536   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    537   // expected-note@+1 {{expected assignment expression}}
    538   a = 2 * b;
    539 #pragma omp atomic capture
    540   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    541   // expected-note@+1 {{expected assignment expression}}
    542   a = b + *&a;
    543 #pragma omp atomic capture
    544   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    545   // expected-note@+1 {{expected exactly two expression statements}}
    546   { a = b; }
    547 #pragma omp atomic capture
    548   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    549   // expected-note@+1 {{expected exactly two expression statements}}
    550   {}
    551 #pragma omp atomic capture
    552   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    553   // expected-note@+1 {{expected in right hand side of the first expression}}
    554   {a = b;a = b;}
    555 #pragma omp atomic capture
    556   // expected-error@+2 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}}
    557   // expected-note@+1 {{expected in right hand side of the first expression}}
    558   {a = b; a = b || a;}
    559 #pragma omp atomic capture
    560   {b = a; a = a && b;}
    561 #pragma omp atomic capture
    562   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    563   // expected-note@+1 {{expected in right hand side of expression}}
    564   b = a = (float)a + b;
    565 #pragma omp atomic capture
    566   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    567   // expected-note@+1 {{expected in right hand side of expression}}
    568   b = a = 2 * b;
    569 #pragma omp atomic capture
    570   // expected-error@+2 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}}
    571   // expected-note@+1 {{expected in right hand side of expression}}
    572   b = a = b + *&a;
    573 #pragma omp atomic capture
    574   c = *&a = *&a +  2;
    575 #pragma omp atomic capture
    576   c = a++;
    577 #pragma omp atomic capture
    578   c = ++a;
    579 #pragma omp atomic capture
    580   c = a--;
    581 #pragma omp atomic capture
    582   c = --a;
    583 #pragma omp atomic capture
    584   c = a += b;
    585 #pragma omp atomic capture
    586   c = a %= b;
    587 #pragma omp atomic capture
    588   c = a *= b;
    589 #pragma omp atomic capture
    590   c = a -= b;
    591 #pragma omp atomic capture
    592   c = a /= b;
    593 #pragma omp atomic capture
    594   c = a &= b;
    595 #pragma omp atomic capture
    596   c = a ^= b;
    597 #pragma omp atomic capture
    598   c = a |= b;
    599 #pragma omp atomic capture
    600   c = a <<= b;
    601 #pragma omp atomic capture
    602   c = a >>= b;
    603 #pragma omp atomic capture
    604   c = a = b + a;
    605 #pragma omp atomic capture
    606   c = a = a * b;
    607 #pragma omp atomic capture
    608   c = a = b - a;
    609 #pragma omp atomic capture
    610   c = a = a / b;
    611 #pragma omp atomic capture
    612   c = a = b & a;
    613 #pragma omp atomic capture
    614   c = a = a ^ b;
    615 #pragma omp atomic capture
    616   c = a = b | a;
    617 #pragma omp atomic capture
    618   c = a = a << b;
    619 #pragma omp atomic capture
    620   c = a = b >> a;
    621 #pragma omp atomic capture
    622   { c = *&a; *&a = *&a +  2;}
    623 #pragma omp atomic capture
    624   { *&a = *&a +  2; c = *&a;}
    625 #pragma omp atomic capture
    626   {c = a; a++;}
    627 #pragma omp atomic capture
    628   {++a;c = a;}
    629 #pragma omp atomic capture
    630   {c = a;a--;}
    631 #pragma omp atomic capture
    632   {--a;c = a;}
    633 #pragma omp atomic capture
    634   {c = a; a += b;}
    635 #pragma omp atomic capture
    636   {a %= b; c = a;}
    637 #pragma omp atomic capture
    638   {c = a; a *= b;}
    639 #pragma omp atomic capture
    640   {a -= b;c = a;}
    641 #pragma omp atomic capture
    642   {c = a; a /= b;}
    643 #pragma omp atomic capture
    644   {a &= b; c = a;}
    645 #pragma omp atomic capture
    646   {c = a; a ^= b;}
    647 #pragma omp atomic capture
    648   {a |= b; c = a;}
    649 #pragma omp atomic capture
    650   {c = a; a <<= b;}
    651 #pragma omp atomic capture
    652   {a >>= b; c = a;}
    653 #pragma omp atomic capture
    654   {c = a; a = b + a;}
    655 #pragma omp atomic capture
    656   {a = a * b; c = a;}
    657 #pragma omp atomic capture
    658   {c = a; a = b - a;}
    659 #pragma omp atomic capture
    660   {a = a / b; c = a;}
    661 #pragma omp atomic capture
    662   {c = a; a = b & a;}
    663 #pragma omp atomic capture
    664   {a = a ^ b; c = a;}
    665 #pragma omp atomic capture
    666   {c = a; a = b | a;}
    667 #pragma omp atomic capture
    668   {a = a << b; c = a;}
    669 #pragma omp atomic capture
    670   {c = a; a = b >> a;}
    671 #pragma omp atomic capture
    672   {c = a; a = foo();}
    673   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
    674 #pragma omp atomic capture capture
    675   b = a /= b;
    676 
    677   // expected-note@+1 {{in instantiation of function template specialization 'capture<int>' requested here}}
    678   return capture<int>();
    679 }
    680 
    681 template <class T>
    682 T seq_cst() {
    683   T a, b = 0;
    684 // Test for atomic seq_cst
    685 #pragma omp atomic seq_cst
    686   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    687   // expected-note@+1 {{expected an expression statement}}
    688   ;
    689 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
    690 #pragma omp atomic seq_cst seq_cst
    691   a += b;
    692 
    693 #pragma omp atomic update seq_cst
    694   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    695   // expected-note@+1 {{expected an expression statement}}
    696   ;
    697 
    698   return T();
    699 }
    700 
    701 int seq_cst() {
    702   int a, b = 0;
    703 // Test for atomic seq_cst
    704 #pragma omp atomic seq_cst
    705   // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    706   // expected-note@+1 {{expected an expression statement}}
    707   ;
    708 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
    709 #pragma omp atomic seq_cst seq_cst
    710   a += b;
    711 
    712 #pragma omp atomic update seq_cst
    713   // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
    714   // expected-note@+1 {{expected an expression statement}}
    715   ;
    716 
    717  return seq_cst<int>();
    718 }
    719 
    720 template <class T>
    721 T mixed() {
    722   T a, b = T();
    723 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    724 // expected-note@+1 2 {{'read' clause used here}}
    725 #pragma omp atomic read write
    726   a = b;
    727 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    728 // expected-note@+1 2 {{'write' clause used here}}
    729 #pragma omp atomic write read
    730   a = b;
    731 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    732 // expected-note@+1 2 {{'update' clause used here}}
    733 #pragma omp atomic update read
    734   a += b;
    735 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    736 // expected-note@+1 2 {{'capture' clause used here}}
    737 #pragma omp atomic capture read
    738   a = ++b;
    739   return T();
    740 }
    741 
    742 int mixed() {
    743   int a, b = 0;
    744 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    745 // expected-note@+1 {{'read' clause used here}}
    746 #pragma omp atomic read write
    747   a = b;
    748 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    749 // expected-note@+1 {{'write' clause used here}}
    750 #pragma omp atomic write read
    751   a = b;
    752 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    753 // expected-note@+1 {{'write' clause used here}}
    754 #pragma omp atomic write update
    755   a = b;
    756 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
    757 // expected-note@+1 {{'write' clause used here}}
    758 #pragma omp atomic write capture
    759   a = b;
    760   // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}}
    761   return mixed<int>();
    762 }
    763 
    764