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 template <class T> 25 T read() { 26 T a, b = 0; 27 // Test for atomic read 28 #pragma omp atomic read 29 // expected-error@+1 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both l-value expressions with scalar type}} 30 ; 31 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} 32 #pragma omp atomic read read 33 a = b; 34 35 return T(); 36 } 37 38 int read() { 39 int a, b = 0; 40 // Test for atomic read 41 #pragma omp atomic read 42 // expected-error@+1 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both l-value expressions with scalar type}} 43 ; 44 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} 45 #pragma omp atomic read read 46 a = b; 47 48 return read<int>(); 49 } 50 51 template <class T> 52 T write() { 53 T a, b = 0; 54 // Test for atomic write 55 #pragma omp atomic write 56 // expected-error@+1 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is an l-value expression with scalar type}} 57 ; 58 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 59 #pragma omp atomic write write 60 a = b; 61 62 return T(); 63 } 64 65 int write() { 66 int a, b = 0; 67 // Test for atomic write 68 #pragma omp atomic write 69 // expected-error@+1 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is an l-value expression with scalar type}} 70 ; 71 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} 72 #pragma omp atomic write write 73 a = b; 74 75 return write<int>(); 76 } 77 78 template <class T> 79 T update() { 80 T a, b = 0; 81 // Test for atomic update 82 #pragma omp atomic update 83 // 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}} 84 ; 85 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} 86 #pragma omp atomic update update 87 a += b; 88 89 #pragma omp atomic 90 // 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}} 91 ; 92 93 return T(); 94 } 95 96 int update() { 97 int a, b = 0; 98 // Test for atomic update 99 #pragma omp atomic update 100 // 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}} 101 ; 102 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} 103 #pragma omp atomic update update 104 a += b; 105 106 #pragma omp atomic 107 // 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}} 108 ; 109 110 return update<int>(); 111 } 112 113 template <class T> 114 T capture() { 115 T a, b = 0; 116 // Test for atomic capture 117 #pragma omp atomic capture 118 // 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}} 119 ++a; 120 #pragma omp atomic capture 121 // 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}} 122 ; 123 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} 124 #pragma omp atomic capture capture 125 a = ++b; 126 127 return T(); 128 } 129 130 int capture() { 131 int a, b = 0; 132 // Test for atomic capture 133 #pragma omp atomic capture 134 // 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}} 135 ++a; 136 #pragma omp atomic capture 137 // 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}} 138 ; 139 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} 140 #pragma omp atomic capture capture 141 a = ++b; 142 143 return capture<int>(); 144 } 145 146 template <class T> 147 T seq_cst() { 148 T a, b = 0; 149 // Test for atomic seq_cst 150 #pragma omp atomic seq_cst 151 // 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}} 152 ; 153 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} 154 #pragma omp atomic seq_cst seq_cst 155 a += b; 156 157 #pragma omp atomic update seq_cst 158 // 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}} 159 ; 160 161 return T(); 162 } 163 164 int seq_cst() { 165 int a, b = 0; 166 // Test for atomic seq_cst 167 #pragma omp atomic seq_cst 168 // 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}} 169 ; 170 // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} 171 #pragma omp atomic seq_cst seq_cst 172 a += b; 173 174 #pragma omp atomic update seq_cst 175 // 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}} 176 ; 177 178 return seq_cst<int>(); 179 } 180 181 template <class T> 182 T mixed() { 183 T a, b = T(); 184 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 185 // expected-note@+1 2 {{'read' clause used here}} 186 #pragma omp atomic read write 187 a = b; 188 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 189 // expected-note@+1 2 {{'write' clause used here}} 190 #pragma omp atomic write read 191 a = b; 192 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 193 // expected-note@+1 2 {{'update' clause used here}} 194 #pragma omp atomic update read 195 a += b; 196 // expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 197 // expected-note@+1 2 {{'capture' clause used here}} 198 #pragma omp atomic capture read 199 a = ++b; 200 return T(); 201 } 202 203 int mixed() { 204 int a, b = 0; 205 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 206 // expected-note@+1 {{'read' clause used here}} 207 #pragma omp atomic read write 208 a = b; 209 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 210 // expected-note@+1 {{'write' clause used here}} 211 #pragma omp atomic write read 212 a = b; 213 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 214 // expected-note@+1 {{'write' clause used here}} 215 #pragma omp atomic write update 216 a = b; 217 // expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} 218 // expected-note@+1 {{'write' clause used here}} 219 #pragma omp atomic write capture 220 a = b; 221 // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}} 222 return mixed<int>(); 223 } 224 225