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 }; 29 30 int readint() { 31 int a = 0, b = 0; 32 // Test for atomic read 33 #pragma omp atomic read 34 // 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}} 35 // expected-note@+1 {{expected an expression statement}} 36 ; 37 #pragma omp atomic read 38 // 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}} 39 // expected-note@+1 {{expected built-in assignment operator}} 40 foo(); 41 #pragma omp atomic read 42 // 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}} 43 // expected-note@+1 {{expected built-in assignment operator}} 44 a += b; 45 #pragma omp atomic read 46 // 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}} 47 // expected-note@+1 {{expected lvalue expression}} 48 a = 0; 49 #pragma omp atomic read 50 a = b; 51 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} 52 #pragma omp atomic read read 53 a = b; 54 55 return 0; 56 } 57 58 int readS() { 59 struct S a, b; 60 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} 61 #pragma omp atomic read read 62 // 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}} 63 // expected-note@+1 {{expected expression of scalar type}} 64 a = b; 65 66 return a.a; 67 } 68 69 int writeint() { 70 int a = 0, b = 0; 71 // Test for atomic write 72 #pragma omp atomic write 73 // 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}} 74 // expected-note@+1 {{expected an expression statement}} 75 ; 76 #pragma omp atomic write 77 // 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}} 78 // expected-note@+1 {{expected built-in assignment operator}} 79 foo(); 80 #pragma omp atomic write 81 // 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}} 82 // expected-note@+1 {{expected built-in assignment operator}} 83 a += b; 84 #pragma omp atomic write 85 a = 0; 86 #pragma omp atomic write 87 a = b; 88 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 89 #pragma omp atomic write write 90 a = b; 91 92 return 0; 93 } 94 95 int writeS() { 96 struct S a, b; 97 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 98 #pragma omp atomic write write 99 // 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}} 100 // expected-note@+1 {{expected expression of scalar type}} 101 a = b; 102 103 return a.a; 104 } 105 106 int updateint() { 107 int a = 0, b = 0; 108 // Test for atomic update 109 #pragma omp atomic update 110 // 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}} 111 // expected-note@+1 {{expected an expression statement}} 112 ; 113 #pragma omp atomic 114 // 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}} 115 // expected-note@+1 {{expected built-in binary or unary operator}} 116 foo(); 117 #pragma omp atomic 118 // 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}} 119 // expected-note@+1 {{expected built-in binary operator}} 120 a = b; 121 #pragma omp atomic update 122 // 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}} 123 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} 124 a = b || a; 125 #pragma omp atomic update 126 // 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}} 127 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} 128 a = a && b; 129 #pragma omp atomic update 130 // 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}} 131 // expected-note@+1 {{expected in right hand side of expression}} 132 a = (float)a + b; 133 #pragma omp atomic 134 // 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}} 135 // expected-note@+1 {{expected in right hand side of expression}} 136 a = 2 * b; 137 #pragma omp atomic 138 // 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}} 139 // expected-note@+1 {{expected in right hand side of expression}} 140 a = b + *&a; 141 #pragma omp atomic update 142 *&a = *&a + 2; 143 #pragma omp atomic update 144 a++; 145 #pragma omp atomic 146 ++a; 147 #pragma omp atomic update 148 a--; 149 #pragma omp atomic 150 --a; 151 #pragma omp atomic update 152 a += b; 153 #pragma omp atomic 154 a %= b; 155 #pragma omp atomic update 156 a *= b; 157 #pragma omp atomic 158 a -= b; 159 #pragma omp atomic update 160 a /= b; 161 #pragma omp atomic 162 a &= b; 163 #pragma omp atomic update 164 a ^= b; 165 #pragma omp atomic 166 a |= b; 167 #pragma omp atomic update 168 a <<= b; 169 #pragma omp atomic 170 a >>= b; 171 #pragma omp atomic update 172 a = b + a; 173 #pragma omp atomic 174 a = a * b; 175 #pragma omp atomic update 176 a = b - a; 177 #pragma omp atomic 178 a = a / b; 179 #pragma omp atomic update 180 a = b & a; 181 #pragma omp atomic 182 a = a ^ b; 183 #pragma omp atomic update 184 a = b | a; 185 #pragma omp atomic 186 a = a << b; 187 #pragma omp atomic 188 a = b >> a; 189 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} 190 #pragma omp atomic update update 191 a /= b; 192 193 return 0; 194 } 195 196 int captureint() { 197 int a = 0, b = 0, c = 0; 198 // Test for atomic capture 199 #pragma omp atomic capture 200 // 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}} 201 // expected-note@+1 {{expected compound statement}} 202 ; 203 #pragma omp atomic capture 204 // 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}} 205 // expected-note@+1 {{expected assignment expression}} 206 foo(); 207 #pragma omp atomic capture 208 // 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}} 209 // expected-note@+1 {{expected built-in binary or unary operator}} 210 a = b; 211 #pragma omp atomic capture 212 // 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}} 213 // expected-note@+1 {{expected assignment expression}} 214 a = b || a; 215 #pragma omp atomic capture 216 // 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}} 217 // expected-note@+1 {{expected one of '+', '*', '-', '/', '&', '^', '|', '<<', or '>>' built-in operations}} 218 b = a = a && b; 219 #pragma omp atomic capture 220 // 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}} 221 // expected-note@+1 {{expected assignment expression}} 222 a = (float)a + b; 223 #pragma omp atomic capture 224 // 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}} 225 // expected-note@+1 {{expected assignment expression}} 226 a = 2 * b; 227 #pragma omp atomic capture 228 // 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}} 229 // expected-note@+1 {{expected assignment expression}} 230 a = b + *&a; 231 #pragma omp atomic capture 232 // 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}} 233 // expected-note@+1 {{expected exactly two expression statements}} 234 { a = b; } 235 #pragma omp atomic capture 236 // 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}} 237 // expected-note@+1 {{expected exactly two expression statements}} 238 {} 239 #pragma omp atomic capture 240 // 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}} 241 // expected-note@+1 {{expected in right hand side of the first expression}} 242 {a = b;a = b;} 243 #pragma omp atomic capture 244 // 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}} 245 // expected-note@+1 {{expected in right hand side of the first expression}} 246 {a = b; a = b || a;} 247 #pragma omp atomic capture 248 {b = a; a = a && b;} 249 #pragma omp atomic capture 250 // 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}} 251 // expected-note@+1 {{expected in right hand side of expression}} 252 b = a = (float)a + b; 253 #pragma omp atomic capture 254 // 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}} 255 // expected-note@+1 {{expected in right hand side of expression}} 256 b = a = 2 * b; 257 #pragma omp atomic capture 258 // 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}} 259 // expected-note@+1 {{expected in right hand side of expression}} 260 b = a = b + *&a; 261 #pragma omp atomic capture 262 c = *&a = *&a + 2; 263 #pragma omp atomic capture 264 c = a++; 265 #pragma omp atomic capture 266 c = ++a; 267 #pragma omp atomic capture 268 c = a--; 269 #pragma omp atomic capture 270 c = --a; 271 #pragma omp atomic capture 272 c = a += b; 273 #pragma omp atomic capture 274 c = a %= b; 275 #pragma omp atomic capture 276 c = a *= b; 277 #pragma omp atomic capture 278 c = a -= b; 279 #pragma omp atomic capture 280 c = a /= b; 281 #pragma omp atomic capture 282 c = a &= b; 283 #pragma omp atomic capture 284 c = a ^= b; 285 #pragma omp atomic capture 286 c = a |= b; 287 #pragma omp atomic capture 288 c = a <<= b; 289 #pragma omp atomic capture 290 c = a >>= b; 291 #pragma omp atomic capture 292 c = a = b + a; 293 #pragma omp atomic capture 294 c = a = a * b; 295 #pragma omp atomic capture 296 c = a = b - a; 297 #pragma omp atomic capture 298 c = a = a / b; 299 #pragma omp atomic capture 300 c = a = b & a; 301 #pragma omp atomic capture 302 c = a = a ^ b; 303 #pragma omp atomic capture 304 c = a = b | a; 305 #pragma omp atomic capture 306 c = a = a << b; 307 #pragma omp atomic capture 308 c = a = b >> a; 309 #pragma omp atomic capture 310 { c = *&a; *&a = *&a + 2;} 311 #pragma omp atomic capture 312 { *&a = *&a + 2; c = *&a;} 313 #pragma omp atomic capture 314 {c = a; a++;} 315 #pragma omp atomic capture 316 {++a;c = a;} 317 #pragma omp atomic capture 318 {c = a;a--;} 319 #pragma omp atomic capture 320 {--a;c = a;} 321 #pragma omp atomic capture 322 {c = a; a += b;} 323 #pragma omp atomic capture 324 {a %= b; c = a;} 325 #pragma omp atomic capture 326 {c = a; a *= b;} 327 #pragma omp atomic capture 328 {a -= b;c = a;} 329 #pragma omp atomic capture 330 {c = a; a /= b;} 331 #pragma omp atomic capture 332 {a &= b; c = a;} 333 #pragma omp atomic capture 334 {c = a; a ^= b;} 335 #pragma omp atomic capture 336 {a |= b; c = a;} 337 #pragma omp atomic capture 338 {c = a; a <<= b;} 339 #pragma omp atomic capture 340 {a >>= b; c = a;} 341 #pragma omp atomic capture 342 {c = a; a = b + a;} 343 #pragma omp atomic capture 344 {a = a * b; c = a;} 345 #pragma omp atomic capture 346 {c = a; a = b - a;} 347 #pragma omp atomic capture 348 {a = a / b; c = a;} 349 #pragma omp atomic capture 350 {c = a; a = b & a;} 351 #pragma omp atomic capture 352 {a = a ^ b; c = a;} 353 #pragma omp atomic capture 354 {c = a; a = b | a;} 355 #pragma omp atomic capture 356 {a = a << b; c = a;} 357 #pragma omp atomic capture 358 {c = a; a = b >> a;} 359 #pragma omp atomic capture 360 {c = a; a = foo();} 361 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} 362 #pragma omp atomic capture capture 363 b = a /= b; 364 365 return 0; 366 } 367 368