1// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
2// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
3// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
4
5void foo() {
6}
7
8bool foobool(int argc) {
9  return argc;
10}
11
12struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
13extern S1 a;
14class S2 {
15  mutable int a;
16  S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
17
18public:
19  S2() : a(0) {}
20  S2(S2 &s2) : a(s2.a) {}
21  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
22  static const float S2sc;
23};
24const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
25S2 b;                     // expected-note 3 {{'b' defined here}}
26const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
27class S3 {
28  int a;
29
30public:
31  int b;
32  S3() : a(0) {}
33  S3(const S3 &s3) : a(s3.a) {}
34  S3 operator+(const S3 &arg1) { return arg1; }
35};
36int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
37S3 c;               // expected-note 3 {{'c' defined here}}
38const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
39extern const int f; // expected-note 4 {{'f' declared here}}
40class S4 {
41  int a;
42  S4(); // expected-note {{implicitly declared private here}}
43  S4(const S4 &s4);
44  S4 &operator+(const S4 &arg) { return (*this); }
45
46public:
47  S4(int v) : a(v) {}
48};
49S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
50class S5 {
51  int a;
52  S5() : a(0) {} // expected-note {{implicitly declared private here}}
53  S5(const S5 &s5) : a(s5.a) {}
54  S5 &operator+(const S5 &arg);
55
56public:
57  S5(int v) : a(v) {}
58};
59class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
60#if __cplusplus >= 201103L // C++11 or later
61// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
62#endif
63  int a;
64
65public:
66  S6() : a(6) {}
67  operator int() { return 6; }
68} o;
69
70S3 h, k;
71#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
72
73template <class T>       // expected-note {{declared here}}
74T tmain(T argc) {
75  const T d = T();       // expected-note 4 {{'d' defined here}}
76  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
77  T qa[5] = {T()};
78  T i;
79  T &j = i;                // expected-note 4 {{'j' defined here}}
80  S3 &p = k;               // expected-note 2 {{'p' defined here}}
81  const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
82  T &q = qa[(int)i];       // expected-note 2 {{'q' defined here}}
83  T fl;
84#pragma omp parallel
85#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
86  {
87    foo();
88  }
89#pragma omp parallel
90#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
91  {
92    foo();
93  }
94#pragma omp parallel
95#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
96  {
97    foo();
98  }
99#pragma omp parallel
100#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
101  {
102    foo();
103  }
104#pragma omp parallel
105#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
106  {
107    foo();
108  }
109#pragma omp parallel
110#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
111  {
112    foo();
113  }
114#pragma omp parallel
115#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
116  {
117    foo();
118  }
119#pragma omp parallel
120#pragma omp sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
121  {
122    foo();
123  }
124#pragma omp parallel
125#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
126  {
127    foo();
128  }
129#pragma omp parallel
130#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
131  {
132    foo();
133  }
134#pragma omp parallel
135#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
136  {
137    foo();
138  }
139#pragma omp parallel
140#pragma omp sections reduction(&& : argc)
141  {
142    foo();
143  }
144#pragma omp parallel
145#pragma omp sections reduction(^ : T) // expected-error {{'T' does not refer to a value}}
146  {
147    foo();
148  }
149#pragma omp parallel
150#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
151  {
152    foo();
153  }
154#pragma omp parallel
155#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
156  {
157    foo();
158  }
159#pragma omp parallel
160#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
161  {
162    foo();
163  }
164#pragma omp parallel
165#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
166  {
167    foo();
168  }
169#pragma omp parallel
170#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
171  {
172    foo();
173  }
174#pragma omp parallel
175#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
176  {
177    foo();
178  }
179#pragma omp parallel
180#pragma omp sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
181  {
182    foo();
183  }
184#pragma omp parallel
185#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
186  {
187    foo();
188  }
189#pragma omp parallel
190#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
191  {
192    foo();
193  }
194#pragma omp parallel
195#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
196  {
197    foo();
198  }
199#pragma omp parallel
200#pragma omp sections reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
201  {
202    foo();
203  }
204#pragma omp parallel
205#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
206  {
207    foo();
208  }
209#pragma omp parallel private(k)
210#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
211  {
212    foo();
213  }
214#pragma omp parallel
215#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
216  {
217    foo();
218  }
219#pragma omp parallel
220#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
221  {
222    foo();
223  }
224#pragma omp parallel shared(i)
225#pragma omp parallel reduction(min : i)
226#pragma omp sections reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
227  {
228    foo();
229  }
230#pragma omp parallel private(fl)       // expected-note 2 {{defined as private}}
231#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
232  {
233    foo();
234  }
235#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}}
236#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
237  {
238    foo();
239  }
240
241  return T();
242}
243
244namespace A {
245double x;
246#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
247}
248namespace B {
249using A::x;
250}
251
252int main(int argc, char **argv) {
253  const int d = 5;       // expected-note 2 {{'d' defined here}}
254  const int da[5] = {0}; // expected-note {{'da' defined here}}
255  int qa[5] = {0};
256  S4 e(4);
257  S5 g(5);
258  int i;
259  int &j = i;           // expected-note 2 {{'j' defined here}}
260  S3 &p = k;            // expected-note 2 {{'p' defined here}}
261  const int &r = da[i]; // expected-note {{'r' defined here}}
262  int &q = qa[i];       // expected-note {{'q' defined here}}
263  float fl;
264#pragma omp parallel
265#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
266  {
267    foo();
268  }
269#pragma omp parallel
270#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
271  {
272    foo();
273  }
274#pragma omp parallel
275#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
276  {
277    foo();
278  }
279#pragma omp parallel
280#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
281  {
282    foo();
283  }
284#pragma omp parallel
285#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
286  {
287    foo();
288  }
289#pragma omp parallel
290#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
291  {
292    foo();
293  }
294#pragma omp parallel
295#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
296  {
297    foo();
298  }
299#pragma omp parallel
300#pragma omp sections reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
301  {
302    foo();
303  }
304#pragma omp parallel
305#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
306  {
307    foo();
308  }
309#pragma omp parallel
310#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
311  {
312    foo();
313  }
314#pragma omp parallel
315#pragma omp sections reduction(~ : argc) // expected-error {{expected unqualified-id}}
316  {
317    foo();
318  }
319#pragma omp parallel
320#pragma omp sections reduction(&& : argc)
321  {
322    foo();
323  }
324#pragma omp parallel
325#pragma omp sections reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
326  {
327    foo();
328  }
329#pragma omp parallel
330#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
331  {
332    foo();
333  }
334#pragma omp parallel
335#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
336  {
337    foo();
338  }
339#pragma omp parallel
340#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
341  {
342    foo();
343  }
344#pragma omp parallel
345#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
346  {
347    foo();
348  }
349#pragma omp parallel
350#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
351  {
352    foo();
353  }
354#pragma omp parallel
355#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
356  {
357    foo();
358  }
359#pragma omp parallel
360#pragma omp sections reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
361  {
362    foo();
363  }
364#pragma omp parallel
365#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
366  {
367    foo();
368  }
369#pragma omp parallel
370#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
371  {
372    foo();
373  }
374#pragma omp parallel
375#pragma omp sections reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
376  {
377    foo();
378  }
379#pragma omp parallel
380#pragma omp sections reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
381  {
382    foo();
383  }
384#pragma omp parallel
385#pragma omp sections reduction(+ : o) // expected-error {{no viable overloaded '='}}
386  {
387    foo();
388  }
389#pragma omp parallel
390#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
391  {
392    foo();
393  }
394#pragma omp parallel private(k)
395#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
396  {
397    foo();
398  }
399#pragma omp parallel
400#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
401  {
402    foo();
403  }
404#pragma omp parallel
405#pragma omp sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
406  {
407    foo();
408  }
409#pragma omp parallel shared(i)
410#pragma omp parallel reduction(min : i)
411#pragma omp sections reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
412  {
413    foo();
414  }
415#pragma omp parallel private(fl)       // expected-note {{defined as private}}
416#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
417  {
418    foo();
419  }
420#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}}
421#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
422  {
423    foo();
424  }
425  static int m;
426#pragma omp sections reduction(+ : m) // OK
427  {
428    foo();
429  }
430
431  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
432}
433