1 // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s 2 3 int foo() { 4 L1: 5 foo(); 6 #pragma omp atomic 7 // expected-error@+1 {{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 { 9 foo(); 10 goto L1; // expected-error {{use of undeclared label 'L1'}} 11 } 12 goto L2; // expected-error {{use of undeclared label 'L2'}} 13 #pragma omp atomic 14 // expected-error@+1 {{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}} 15 { 16 foo(); 17 L2: 18 foo(); 19 } 20 21 return 0; 22 } 23 24 struct S { 25 int a; 26 S &operator=(int v) { 27 a = v; 28 return *this; 29 } 30 S &operator+=(const S &s) { 31 a += s.a; 32 return *this; 33 } 34 }; 35 36 template <class T> 37 T read() { 38 T a = T(), b = T(); 39 // Test for atomic read 40 #pragma omp atomic read 41 // 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}} 42 // expected-note@+1 {{expected an expression statement}} 43 ; 44 #pragma omp atomic read 45 // 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}} 46 // expected-note@+1 {{expected built-in assignment operator}} 47 foo(); 48 #pragma omp atomic read 49 // 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}} 50 // expected-note@+1 {{expected built-in assignment operator}} 51 a += b; 52 #pragma omp atomic read 53 // 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}} 54 // expected-note@+1 {{expected lvalue expression}} 55 a = 0; 56 #pragma omp atomic read 57 // 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}} 58 // expected-note@+1 {{expected built-in assignment operator}} 59 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 built-in assignment operator}} 64 a = b; 65 66 return a; 67 } 68 69 int read() { 70 int a = 0, b = 0; 71 // Test for atomic read 72 #pragma omp atomic read 73 // 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}} 74 // expected-note@+1 {{expected an expression statement}} 75 ; 76 #pragma omp atomic read 77 // 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}} 78 // expected-note@+1 {{expected built-in assignment operator}} 79 foo(); 80 #pragma omp atomic read 81 // 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}} 82 // expected-note@+1 {{expected built-in assignment operator}} 83 a += b; 84 #pragma omp atomic read 85 // 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}} 86 // expected-note@+1 {{expected lvalue expression}} 87 a = 0; 88 #pragma omp atomic read 89 a = b; 90 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} 91 #pragma omp atomic read read 92 a = b; 93 94 // expected-note@+1 {{in instantiation of function template specialization 'read<S>' requested here}} 95 return read<int>() + read<S>().a; 96 } 97 98 template <class T> 99 T write() { 100 T a, b = 0; 101 // Test for atomic write 102 #pragma omp atomic write 103 // 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}} 104 // expected-note@+1 {{expected an expression statement}} 105 ; 106 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 107 #pragma omp atomic write write 108 a = b; 109 #pragma omp atomic write 110 // 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}} 111 // expected-note@+1 {{expected built-in assignment operator}} 112 foo(); 113 #pragma omp atomic write 114 // 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}} 115 // expected-note@+1 {{expected built-in assignment operator}} 116 a += b; 117 #pragma omp atomic write 118 a = 0; 119 #pragma omp atomic write 120 a = b; 121 122 return T(); 123 } 124 125 int write() { 126 int a, b = 0; 127 // Test for atomic write 128 #pragma omp atomic write 129 // 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}} 130 // expected-note@+1 {{expected an expression statement}} 131 ; 132 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 133 #pragma omp atomic write write 134 a = b; 135 #pragma omp atomic write 136 // 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}} 137 // expected-note@+1 {{expected built-in assignment operator}} 138 foo(); 139 #pragma omp atomic write 140 // 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}} 141 // expected-note@+1 {{expected built-in assignment operator}} 142 a += b; 143 #pragma omp atomic write 144 a = 0; 145 #pragma omp atomic write 146 a = foo(); 147 148 return write<int>(); 149 } 150 151 template <class T> 152 T update() { 153 T a, b = 0; 154 // Test for atomic update 155 #pragma omp atomic update 156 // expected-error@+1 {{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}} 157 ; 158 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} 159 #pragma omp atomic update update 160 a += b; 161 162 #pragma omp atomic 163 // expected-error@+1 {{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}} 164 ; 165 166 return T(); 167 } 168 169 int update() { 170 int a, b = 0; 171 // Test for atomic update 172 #pragma omp atomic update 173 // expected-error@+1 {{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}} 174 ; 175 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} 176 #pragma omp atomic update update 177 a += b; 178 179 #pragma omp atomic 180 // expected-error@+1 {{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}} 181 ; 182 183 return update<int>(); 184 } 185 186 template <class T> 187 T capture() { 188 T a, b = 0; 189 // Test for atomic capture 190 #pragma omp atomic capture 191 // expected-error@+1 {{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}} 192 ++a; 193 #pragma omp atomic capture 194 // expected-error@+1 {{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}} 195 ; 196 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} 197 #pragma omp atomic capture capture 198 a = ++b; 199 200 return T(); 201 } 202 203 int capture() { 204 int a, b = 0; 205 // Test for atomic capture 206 #pragma omp atomic capture 207 // expected-error@+1 {{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}} 208 ++a; 209 #pragma omp atomic capture 210 // expected-error@+1 {{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}} 211 ; 212 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} 213 #pragma omp atomic capture capture 214 a = ++b; 215 216 return capture<int>(); 217 } 218 219 template <class T> 220 T seq_cst() { 221 T a, b = 0; 222 // Test for atomic seq_cst 223 #pragma omp atomic seq_cst 224 // expected-error@+1 {{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}} 225 ; 226 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} 227 #pragma omp atomic seq_cst seq_cst 228 a += b; 229 230 #pragma omp atomic update seq_cst 231 // expected-error@+1 {{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}} 232 ; 233 234 return T(); 235 } 236 237 int seq_cst() { 238 int a, b = 0; 239 // Test for atomic seq_cst 240 #pragma omp atomic seq_cst 241 // expected-error@+1 {{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}} 242 ; 243 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} 244 #pragma omp atomic seq_cst seq_cst 245 a += b; 246 247 #pragma omp atomic update seq_cst 248 // expected-error@+1 {{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}} 249 ; 250 251 return seq_cst<int>(); 252 } 253 254 template <class T> 255 T mixed() { 256 T a, b = T(); 257 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 258 // expected-note@+1 2 {{'read' clause used here}} 259 #pragma omp atomic read write 260 a = b; 261 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 262 // expected-note@+1 2 {{'write' clause used here}} 263 #pragma omp atomic write read 264 a = b; 265 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 266 // expected-note@+1 2 {{'update' clause used here}} 267 #pragma omp atomic update read 268 a += b; 269 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 270 // expected-note@+1 2 {{'capture' clause used here}} 271 #pragma omp atomic capture read 272 a = ++b; 273 return T(); 274 } 275 276 int mixed() { 277 int a, b = 0; 278 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 279 // expected-note@+1 {{'read' clause used here}} 280 #pragma omp atomic read write 281 a = b; 282 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 283 // expected-note@+1 {{'write' clause used here}} 284 #pragma omp atomic write read 285 a = b; 286 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 287 // expected-note@+1 {{'write' clause used here}} 288 #pragma omp atomic write update 289 a = b; 290 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 291 // expected-note@+1 {{'write' clause used here}} 292 #pragma omp atomic write capture 293 a = b; 294 // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}} 295 return mixed<int>(); 296 } 297 298