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