1 // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
2
foo()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;
operator =S26 S &operator=(int v) {
27 a = v;
28 return *this;
29 }
operator +=S30 S &operator+=(const S &s) {
31 a += s.a;
32 return *this;
33 }
34 };
35
36 template <class T>
read()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
read()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>
write()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
write()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>
update()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
update()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>
capture()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
capture()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>
seq_cst()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
seq_cst()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>
mixed()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
mixed()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