1 // RUN: %clang_cc1 -verify -fopenmp %s
2 
3 // RUN: %clang_cc1 -verify -fopenmp-simd %s
4 
5 namespace X {
6   int x;
7 };
8 
9 struct B {
10   static int ib; // expected-note {{'B::ib' declared here}}
11   static int bfoo() { return 8; }
12 };
13 
14 int bfoo() { return 4; }
15 
16 int z;
17 const int C1 = 1;
18 const int C2 = 2;
19 void test_linear_colons()
20 {
21   int B = 0;
22 
23 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
24 #pragma omp target
25 #pragma omp teams
26 #pragma omp distribute simd linear(B:bfoo())
27   for (int i = 0; i < 10; ++i) ;
28 
29 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
30 #pragma omp target
31 #pragma omp teams
32 #pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
33   for (int i = 0; i < 10; ++i) ;
34 
35 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
36 #pragma omp target
37 #pragma omp teams
38 #pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
39   for (int i = 0; i < 10; ++i) ;
40 
41 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
42 #pragma omp target
43 #pragma omp teams
44 #pragma omp distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
45   for (int i = 0; i < 10; ++i) ;
46 
47 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
48 #pragma omp target
49 #pragma omp teams
50 #pragma omp distribute simd linear(B:B::bfoo())
51   for (int i = 0; i < 10; ++i) ;
52 
53 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
54 #pragma omp target
55 #pragma omp teams
56 #pragma omp distribute simd linear(X::x : ::z)
57   for (int i = 0; i < 10; ++i) ;
58 
59 // expected-error@+3 3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
60 #pragma omp target
61 #pragma omp teams
62 #pragma omp distribute simd linear(B,::z, X::x)
63   for (int i = 0; i < 10; ++i) ;
64 
65 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
66 #pragma omp target
67 #pragma omp teams
68 #pragma omp distribute simd linear(::z)
69   for (int i = 0; i < 10; ++i) ;
70 
71 #pragma omp target
72 #pragma omp teams
73 #pragma omp distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
74   for (int i = 0; i < 10; ++i) ;
75 
76 // expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
77 #pragma omp target
78 #pragma omp teams
79 #pragma omp distribute simd linear(B::ib,B:C1+C2)
80   for (int i = 0; i < 10; ++i) ;
81 }
82 
83 template<int L, class T, class N> T test_template(T* arr, N num) {
84   N i;
85   T sum = (T)0;
86   T ind2 = - num * L; // expected-note {{'ind2' defined here}}
87 
88 #pragma omp target
89 #pragma omp teams
90 #pragma omp distribute simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
91   for (i = 0; i < num; ++i) {
92     T cur = arr[(int)ind2];
93     ind2 += L;
94     sum += cur;
95   }
96   return T();
97 }
98 
99 template<int LEN> int test_warn() {
100   int ind2 = 0;
101   #pragma omp target
102   #pragma omp teams
103   #pragma omp parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
104   for (int i = 0; i < 100; i++) {
105     ind2 += LEN;
106   }
107   return ind2;
108 }
109 
110 struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
111 extern S1 a;
112 class S2 {
113   mutable int a;
114 public:
115   S2():a(0) { }
116 };
117 const S2 b; // expected-note 2 {{'b' defined here}}
118 const S2 ba[5];
119 class S3 {
120   int a;
121 public:
122   S3():a(0) { }
123 };
124 const S3 ca[5];
125 class S4 {
126   int a;
127   S4();
128 public:
129   S4(int v):a(v) { }
130 };
131 class S5 {
132   int a;
133   S5():a(0) {}
134 public:
135   S5(int v):a(v) { }
136 };
137 
138 S3 h;
139 #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
140 
141 template<class I, class C> int foomain(I argc, C **argv) {
142   I e(4);
143   I g(5);
144   int i;
145   int &j = i;
146 
147 #pragma omp target
148 #pragma omp teams
149 #pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}}
150   for (int k = 0; k < argc; ++k) ++k;
151 
152 #pragma omp target
153 #pragma omp teams
154 #pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
155   for (int k = 0; k < argc; ++k) ++k;
156 
157 #pragma omp target
158 #pragma omp teams
159 #pragma omp distribute simd linear () // expected-error {{expected expression}}
160   for (int k = 0; k < argc; ++k) ++k;
161 
162 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
163 #pragma omp target
164 #pragma omp teams
165 #pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
166   for (int k = 0; k < argc; ++k) ++k;
167 
168 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
169 #pragma omp target
170 #pragma omp teams
171 #pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
172   for (int k = 0; k < argc; ++k) ++k;
173 
174 #pragma omp target
175 #pragma omp teams
176 #pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
177   for (int k = 0; k < argc; ++k) ++k;
178 
179 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
180 #pragma omp target
181 #pragma omp teams
182 #pragma omp distribute simd linear (argc : 5)
183   for (int k = 0; k < argc; ++k) ++k;
184 
185 #pragma omp target
186 #pragma omp teams
187 #pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
188   for (int k = 0; k < argc; ++k) ++k;
189 
190 #pragma omp target
191 #pragma omp teams
192 #pragma omp distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
193   for (int k = 0; k < argc; ++k) ++k;
194 
195 #pragma omp target
196 #pragma omp teams
197 #pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}}
198   for (int k = 0; k < argc; ++k) ++k;
199 
200 // expected-error@+3 2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
201 #pragma omp target
202 #pragma omp teams
203 #pragma omp distribute simd linear(e, g)
204   for (int k = 0; k < argc; ++k) ++k;
205 
206 #pragma omp target
207 #pragma omp teams
208 #pragma omp distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
209   for (int k = 0; k < argc; ++k) ++k;
210 
211 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
212 #pragma omp target
213 #pragma omp teams
214 #pragma omp distribute simd linear(i)
215   for (int k = 0; k < argc; ++k) ++k;
216 
217   return 0;
218 }
219 
220 namespace A {
221 double x;
222 #pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
223 }
224 namespace C {
225 using A::x;
226 }
227 
228 int main(int argc, char **argv) {
229   double darr[100];
230   // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
231   test_template<-4>(darr, 4);
232   // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
233   test_warn<0>();
234 
235   S4 e(4); // expected-note {{'e' defined here}}
236   S5 g(5); // expected-note {{'g' defined here}}
237   int i;
238   int &j = i;
239 
240 #pragma omp target
241 #pragma omp teams
242 #pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}}
243   for (int k = 0; k < argc; ++k) ++k;
244 
245 #pragma omp target
246 #pragma omp teams
247 #pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
248   for (int k = 0; k < argc; ++k) ++k;
249 
250 #pragma omp target
251 #pragma omp teams
252 #pragma omp distribute simd linear () // expected-error {{expected expression}}
253   for (int k = 0; k < argc; ++k) ++k;
254 
255 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
256 #pragma omp target
257 #pragma omp teams
258 #pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
259   for (int k = 0; k < argc; ++k) ++k;
260 
261 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
262 #pragma omp target
263 #pragma omp teams
264 #pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
265   for (int k = 0; k < argc; ++k) ++k;
266 
267 #pragma omp target
268 #pragma omp teams
269 #pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
270   for (int k = 0; k < argc; ++k) ++k;
271 
272 // expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
273 #pragma omp target
274 #pragma omp teams
275 #pragma omp distribute simd linear (argc)
276   for (int k = 0; k < argc; ++k) ++k;
277 
278 #pragma omp target
279 #pragma omp teams
280 #pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
281   for (int k = 0; k < argc; ++k) ++k;
282 
283 
284 #pragma omp target
285 #pragma omp teams
286 #pragma omp distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}} expected-warning {{Non-trivial type 'const S2' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}}
287   for (int k = 0; k < argc; ++k) ++k;
288 
289 #pragma omp target
290 #pragma omp teams
291 #pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}}
292   for (int k = 0; k < argc; ++k) ++k;
293 
294 #pragma omp target
295 #pragma omp teams
296 #pragma omp distribute simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}} expected-warning {{Non-trivial type 'S4' is mapped, only trivial types are guaranteed to be mapped correctly}} expected-warning {{Non-trivial type 'S5' is mapped, only trivial types are guaranteed to be mapped correctly}}
297   for (int k = 0; k < argc; ++k) ++k;
298 
299 #pragma omp target
300 #pragma omp teams
301 #pragma omp distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
302   for (int k = 0; k < argc; ++k) ++k;
303 
304   #pragma omp parallel
305   {
306     int k;
307     #pragma omp target
308     #pragma omp teams
309     #pragma omp distribute simd linear(k)
310       for (k = 0; k < argc; ++k) ++k;
311 
312     #pragma omp target
313     #pragma omp teams
314     #pragma omp distribute simd linear(k : 4)
315       for (k = 0; k < argc; k+=4) { }
316   }
317 
318   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
319   return 0;
320 }
321 
322