1 // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
2 
3 void foo() {
4 }
5 
6 #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
7 
8 class S { // expected-note 6 {{'S' declared here}}
9   S(const S &s) { a = s.a + 12; }
10   int a;
11 
12 public:
13   S() : a(0) {}
14   S(int a) : a(a) {}
15   operator int() { return a; }
16   S &operator++() { return *this; }
17   S operator+(const S &) { return *this; }
18 };
19 
20 template <class T>
21 int foo() {
22   T a; // expected-note 3 {{'a' defined here}}
23   T &b = a; // expected-note 4 {{'b' defined here}}
24   int r;
25 #pragma omp task default(none)
26 #pragma omp task default(shared)
27   ++a;
28 // expected-error@+2 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
29 #pragma omp task default(none)
30 #pragma omp task
31 // expected-note@+1 {{used here}}
32   ++a;
33 #pragma omp task
34 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
35 #pragma omp task
36   // expected-note@+1 {{used here}}
37   ++a;
38 #pragma omp task default(shared)
39 #pragma omp task
40   ++a;
41 #pragma omp task
42 #pragma omp parallel
43   ++a;
44 // expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
45 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
46 #pragma omp task
47   // expected-note@+1 2 {{used here}}
48   ++b;
49 // expected-error@+3 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
50 // expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
51 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
52 #pragma omp task
53 // expected-note@+1 3 {{used here}}
54 #pragma omp parallel shared(a, b)
55   ++a, ++b;
56 // expected-note@+1 3 {{defined as reduction}}
57 #pragma omp parallel reduction(+ : r)
58 // expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
59 #pragma omp task firstprivate(r)
60   // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
61   ++r;
62 // expected-note@+1 2 {{defined as reduction}}
63 #pragma omp parallel reduction(+ : r)
64 #pragma omp task default(shared)
65   // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
66   ++r;
67 // expected-note@+1 2 {{defined as reduction}}
68 #pragma omp parallel reduction(+ : r)
69 #pragma omp task
70   // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
71   ++r;
72 #pragma omp parallel
73 // expected-note@+1 3 {{defined as reduction}}
74 #pragma omp for reduction(+ : r)
75   for (int i = 0; i < 10; ++i)
76 // expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
77 #pragma omp task firstprivate(r)
78     // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
79     ++r;
80 #pragma omp parallel
81 // expected-note@+1 2 {{defined as reduction}}
82 #pragma omp for reduction(+ : r)
83   for (int i = 0; i < 10; ++i)
84 #pragma omp task default(shared)
85     // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
86     ++r;
87 #pragma omp parallel
88 // expected-note@+1 2 {{defined as reduction}}
89 #pragma omp for reduction(+ : r)
90   for (int i = 0; i < 10; ++i)
91 #pragma omp task
92     // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
93     ++r;
94 // expected-note@+1 {{non-shared variable in a task construct is predetermined as firstprivate}}
95 #pragma omp task
96 // expected-error@+2 {{reduction variable must be shared}}
97 // expected-error@+1 {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
98 #pragma omp for reduction(+ : r)
99   ++r;
100 // expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'untied' clause}}
101 #pragma omp task untied untied
102   ++r;
103 // expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'mergeable' clause}}
104 #pragma omp task mergeable mergeable
105   ++r;
106   return a + b;
107 }
108 
109 int main(int argc, char **argv) {
110   int a;
111   int &b = a; // expected-note 2 {{'b' defined here}}
112   S sa;       // expected-note 3 {{'sa' defined here}}
113   S &sb = sa; // expected-note 2 {{'sb' defined here}}
114   int r;
115 #pragma omp task { // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
116   foo();
117 #pragma omp task( // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
118   foo();
119 #pragma omp task[ // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
120   foo();
121 #pragma omp task] // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
122   foo();
123 #pragma omp task) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
124   foo();
125 #pragma omp task } // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
126   foo();
127 #pragma omp task
128 // expected-warning@+1 {{extra tokens at the end of '#pragma omp task' are ignored}}
129 #pragma omp task unknown()
130   foo();
131 L1:
132   foo();
133 #pragma omp task
134   ;
135 #pragma omp task
136   {
137     goto L1; // expected-error {{use of undeclared label 'L1'}}
138     argc++;
139   }
140 
141   for (int i = 0; i < 10; ++i) {
142     switch (argc) {
143     case (0):
144 #pragma omp task
145     {
146       foo();
147       break;    // expected-error {{'break' statement not in loop or switch statement}}
148       continue; // expected-error {{'continue' statement not in loop statement}}
149     }
150     default:
151       break;
152     }
153   }
154 #pragma omp task default(none)
155   ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
156 
157   goto L2; // expected-error {{use of undeclared label 'L2'}}
158 #pragma omp task
159 L2:
160   foo();
161 #pragma omp task
162   {
163     return 1; // expected-error {{cannot return from OpenMP region}}
164   }
165 
166   [[]] // expected-error {{an attribute list cannot appear here}}
167 #pragma omp task
168       for (int n = 0; n < 100; ++n) {
169   }
170 
171 #pragma omp task default(none)
172 #pragma omp task default(shared)
173   ++a;
174 #pragma omp task default(none)
175 #pragma omp task
176   ++a;
177 #pragma omp task default(shared)
178 #pragma omp task
179   ++a;
180 #pragma omp task
181 #pragma omp parallel
182   ++a;
183 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
184 #pragma omp task
185   // expected-note@+1 {{used here}}
186   ++b;
187 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
188 #pragma omp task
189 // expected-note@+1 {{used here}}
190 #pragma omp parallel shared(a, b)
191   ++a, ++b;
192 #pragma omp task default(none)
193 #pragma omp task default(shared)
194   ++sa;
195 #pragma omp task default(none)
196 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
197 #pragma omp task
198 // expected-note@+1 {{used here}}
199   ++sa;
200 #pragma omp task
201 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
202 #pragma omp task
203 // expected-note@+1 {{used here}}
204   ++sa;
205 #pragma omp task default(shared)
206 #pragma omp task
207   ++sa;
208 #pragma omp task
209 #pragma omp parallel
210   ++sa;
211 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
212 #pragma omp task
213   // expected-note@+1 {{used here}}
214   ++sb;
215 // expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
216 // expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
217 #pragma omp task
218 // expected-note@+1 2 {{used here}}
219 #pragma omp parallel shared(sa, sb)
220   ++sa, ++sb;
221 // expected-note@+1 2 {{defined as reduction}}
222 #pragma omp parallel reduction(+ : r)
223 // expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
224 #pragma omp task firstprivate(r)
225   // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
226   ++r;
227 // expected-note@+1 {{defined as reduction}}
228 #pragma omp parallel reduction(+ : r)
229 #pragma omp task default(shared)
230   // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
231   ++r;
232 // expected-note@+1 {{defined as reduction}}
233 #pragma omp parallel reduction(+ : r)
234 #pragma omp task
235   // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
236   ++r;
237 #pragma omp parallel
238 // expected-note@+1 2 {{defined as reduction}}
239 #pragma omp for reduction(+ : r)
240   for (int i = 0; i < 10; ++i)
241 // expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
242 #pragma omp task firstprivate(r)
243     // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
244     ++r;
245 #pragma omp parallel
246 // expected-note@+1 {{defined as reduction}}
247 #pragma omp for reduction(+ : r)
248   for (int i = 0; i < 10; ++i)
249 #pragma omp task default(shared)
250     // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
251     ++r;
252 #pragma omp parallel
253 // expected-note@+1 {{defined as reduction}}
254 #pragma omp for reduction(+ : r)
255   for (int i = 0; i < 10; ++i)
256 #pragma omp task
257     // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
258     ++r;
259 // expected-note@+1 {{non-shared variable in a task construct is predetermined as firstprivate}}
260 #pragma omp task
261 // expected-error@+2 {{reduction variable must be shared}}
262 // expected-error@+1 {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
263 #pragma omp for reduction(+ : r)
264   ++r;
265 // expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'untied' clause}}
266 #pragma omp task untied untied
267   ++r;
268 // expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'mergeable' clause}}
269 #pragma omp task mergeable mergeable
270   ++r;
271   // expected-note@+2 {{in instantiation of function template specialization 'foo<int>' requested here}}
272   // expected-note@+1 {{in instantiation of function template specialization 'foo<S>' requested here}}
273   return foo<int>() + foo<S>();
274 }
275 
276