blob: b53133f35240e4d399e18d7f9f75af04f7ae6465 [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
24template <class T>
25T read() {
26 T a, b = 0;
27// Test for atomic read
28#pragma omp atomic read
Alexey Bataev459dec02014-07-24 06:46:57 +000029 // 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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000030 ;
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
38int read() {
39 int a, b = 0;
40// Test for atomic read
41#pragma omp atomic read
Alexey Bataev459dec02014-07-24 06:46:57 +000042 // 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}}
Alexey Bataevf98b00c2014-07-23 02:27:21 +000043 ;
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}
Alexey Bataevdea47612014-07-23 07:46:59 +000050
51template <class T>
52T write() {
53 T a, b = 0;
54// Test for atomic write
55#pragma omp atomic write
Alexey Bataev459dec02014-07-24 06:46:57 +000056 // 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 +000057 ;
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
65int write() {
66 int a, b = 0;
67// Test for atomic write
68#pragma omp atomic write
Alexey Bataev459dec02014-07-24 06:46:57 +000069 // 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 +000070 ;
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
78template <class T>
Alexey Bataev67a4f222014-07-23 10:25:33 +000079T update() {
80 T a, b = 0;
81// Test for atomic update
82#pragma omp atomic update
Alexey Bataev459dec02014-07-24 06:46:57 +000083 // 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 +000084 ;
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
Alexey Bataev459dec02014-07-24 06:46:57 +000090 // 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 +000091 ;
92
93 return T();
94}
95
96int update() {
97 int a, b = 0;
98// Test for atomic update
99#pragma omp atomic update
Alexey Bataev459dec02014-07-24 06:46:57 +0000100 // 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 +0000101 ;
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
Alexey Bataev459dec02014-07-24 06:46:57 +0000107 // 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 +0000108 ;
109
110 return update<int>();
111}
112
113template <class T>
Alexey Bataev459dec02014-07-24 06:46:57 +0000114T 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
130int 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
146template <class T>
Alexey Bataev82bad8b2014-07-24 08:55:34 +0000147T 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
164int 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
181template <class T>
Alexey Bataevdea47612014-07-23 07:46:59 +0000182T 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;
Alexey Bataev67a4f222014-07-23 10:25:33 +0000192// 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;
Alexey Bataev459dec02014-07-24 06:46:57 +0000196// 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;
Alexey Bataevdea47612014-07-23 07:46:59 +0000200 return T();
201}
202
203int 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;
Alexey Bataev67a4f222014-07-23 10:25:33 +0000213// 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;
Alexey Bataev459dec02014-07-24 06:46:57 +0000217// 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}}
Alexey Bataevdea47612014-07-23 07:46:59 +0000222 return mixed<int>();
223}
224