blob: 3965a77c955de3f5d73b3ceae79a3607550a53a2 [file] [log] [blame]
Alexey Bataev0162e452014-07-22 10:10:35 +00001// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
2
3int foo() {
Alexey Bataevf98b00c2014-07-23 02:27:21 +00004L1:
5 foo();
6#pragma omp atomic
Alexey Bataev459dec02014-07-24 06:46:57 +00007 // 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}}
Alexey Bataev0162e452014-07-22 10:10:35 +00008 {
9 foo();
10 goto L1; // expected-error {{use of undeclared label 'L1'}}
11 }
12 goto L2; // expected-error {{use of undeclared label 'L2'}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000013#pragma omp atomic
Alexey Bataev459dec02014-07-24 06:46:57 +000014 // 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}}
Alexey Bataev0162e452014-07-22 10:10:35 +000015 {
16 foo();
Alexey Bataevf98b00c2014-07-23 02:27:21 +000017 L2:
Alexey Bataev0162e452014-07-22 10:10:35 +000018 foo();
19 }
20
21 return 0;
22}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000023
Alexey Bataev62cec442014-11-18 10:14:22 +000024struct 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
Alexey Bataevf98b00c2014-07-23 02:27:21 +000036template <class T>
37T read() {
Alexey Bataev62cec442014-11-18 10:14:22 +000038 T a = T(), b = T();
Alexey Bataevf98b00c2014-07-23 02:27:21 +000039// Test for atomic read
40#pragma omp atomic read
Alexey Bataev62cec442014-11-18 10:14:22 +000041 // 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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000043 ;
Alexey Bataev62cec442014-11-18 10:14:22 +000044#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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000061#pragma omp atomic read read
Alexey Bataev62cec442014-11-18 10:14:22 +000062 // 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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000064 a = b;
65
Alexey Bataev62cec442014-11-18 10:14:22 +000066 return a;
Alexey Bataevf98b00c2014-07-23 02:27:21 +000067}
68
69int read() {
Alexey Bataev62cec442014-11-18 10:14:22 +000070 int a = 0, b = 0;
Alexey Bataevf98b00c2014-07-23 02:27:21 +000071// Test for atomic read
72#pragma omp atomic read
Alexey Bataev62cec442014-11-18 10:14:22 +000073 // 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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000075 ;
Alexey Bataev62cec442014-11-18 10:14:22 +000076#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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000091#pragma omp atomic read read
92 a = b;
93
Alexey Bataev62cec442014-11-18 10:14:22 +000094 // expected-note@+1 {{in instantiation of function template specialization 'read<S>' requested here}}
95 return read<int>() + read<S>().a;
Alexey Bataevf98b00c2014-07-23 02:27:21 +000096}
Alexey Bataevdea47612014-07-23 07:46:59 +000097
98template <class T>
99T write() {
100 T a, b = 0;
101// Test for atomic write
102#pragma omp atomic write
Alexey Bataev459dec02014-07-24 06:46:57 +0000103 // 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}}
Alexey Bataevdea47612014-07-23 07:46:59 +0000104 ;
105// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
106#pragma omp atomic write write
107 a = b;
108
109 return T();
110}
111
112int write() {
113 int a, b = 0;
114// Test for atomic write
115#pragma omp atomic write
Alexey Bataev459dec02014-07-24 06:46:57 +0000116 // 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}}
Alexey Bataevdea47612014-07-23 07:46:59 +0000117 ;
118// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
119#pragma omp atomic write write
120 a = b;
121
122 return write<int>();
123}
124
125template <class T>
Alexey Bataev67a4f222014-07-23 10:25:33 +0000126T update() {
127 T a, b = 0;
128// Test for atomic update
129#pragma omp atomic update
Alexey Bataev459dec02014-07-24 06:46:57 +0000130 // 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}}
Alexey Bataev67a4f222014-07-23 10:25:33 +0000131 ;
132// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
133#pragma omp atomic update update
134 a += b;
135
136#pragma omp atomic
Alexey Bataev459dec02014-07-24 06:46:57 +0000137 // 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}}
Alexey Bataev67a4f222014-07-23 10:25:33 +0000138 ;
139
140 return T();
141}
142
143int update() {
144 int a, b = 0;
145// Test for atomic update
146#pragma omp atomic update
Alexey Bataev459dec02014-07-24 06:46:57 +0000147 // 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}}
Alexey Bataev67a4f222014-07-23 10:25:33 +0000148 ;
149// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}}
150#pragma omp atomic update update
151 a += b;
152
153#pragma omp atomic
Alexey Bataev459dec02014-07-24 06:46:57 +0000154 // 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}}
Alexey Bataev67a4f222014-07-23 10:25:33 +0000155 ;
156
157 return update<int>();
158}
159
160template <class T>
Alexey Bataev459dec02014-07-24 06:46:57 +0000161T capture() {
162 T a, b = 0;
163// Test for atomic capture
164#pragma omp atomic capture
165 // 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}}
166 ++a;
167#pragma omp atomic capture
168 // 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}}
169 ;
170// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
171#pragma omp atomic capture capture
172 a = ++b;
173
174 return T();
175}
176
177int capture() {
178 int a, b = 0;
179// Test for atomic capture
180#pragma omp atomic capture
181 // 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}}
182 ++a;
183#pragma omp atomic capture
184 // 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}}
185 ;
186// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}}
187#pragma omp atomic capture capture
188 a = ++b;
189
190 return capture<int>();
191}
192
193template <class T>
Alexey Bataev82bad8b2014-07-24 08:55:34 +0000194T seq_cst() {
195 T a, b = 0;
196// Test for atomic seq_cst
197#pragma omp atomic seq_cst
198 // 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}}
199 ;
200// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
201#pragma omp atomic seq_cst seq_cst
202 a += b;
203
204#pragma omp atomic update seq_cst
205 // 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}}
206 ;
207
208 return T();
209}
210
211int seq_cst() {
212 int a, b = 0;
213// Test for atomic seq_cst
214#pragma omp atomic seq_cst
215 // 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}}
216 ;
217// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}}
218#pragma omp atomic seq_cst seq_cst
219 a += b;
220
221#pragma omp atomic update seq_cst
222 // 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}}
223 ;
224
225 return seq_cst<int>();
226}
227
228template <class T>
Alexey Bataevdea47612014-07-23 07:46:59 +0000229T mixed() {
230 T a, b = T();
231// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
232// expected-note@+1 2 {{'read' clause used here}}
233#pragma omp atomic read write
234 a = b;
235// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
236// expected-note@+1 2 {{'write' clause used here}}
237#pragma omp atomic write read
238 a = b;
Alexey Bataev67a4f222014-07-23 10:25:33 +0000239// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
240// expected-note@+1 2 {{'update' clause used here}}
241#pragma omp atomic update read
242 a += b;
Alexey Bataev459dec02014-07-24 06:46:57 +0000243// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
244// expected-note@+1 2 {{'capture' clause used here}}
245#pragma omp atomic capture read
246 a = ++b;
Alexey Bataevdea47612014-07-23 07:46:59 +0000247 return T();
248}
249
250int mixed() {
251 int a, b = 0;
252// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
253// expected-note@+1 {{'read' clause used here}}
254#pragma omp atomic read write
255 a = b;
256// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
257// expected-note@+1 {{'write' clause used here}}
258#pragma omp atomic write read
259 a = b;
Alexey Bataev67a4f222014-07-23 10:25:33 +0000260// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
261// expected-note@+1 {{'write' clause used here}}
262#pragma omp atomic write update
263 a = b;
Alexey Bataev459dec02014-07-24 06:46:57 +0000264// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}}
265// expected-note@+1 {{'write' clause used here}}
266#pragma omp atomic write capture
267 a = b;
268 // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}}
Alexey Bataevdea47612014-07-23 07:46:59 +0000269 return mixed<int>();
270}
271