1 // RUN: %clang_cc1 -verify -fopenmp %s
2 
3 // RUN: %clang_cc1 -verify -fopenmp-simd %s
4 
5 extern int omp_default_mem_alloc;
6 namespace X {
7   int x;
8 };
9 
10 struct B {
11   static int ib; // expected-note {{'B::ib' declared here}}
12   static int bfoo() { return 8; }
13 };
14 
15 int bfoo() { return 4; }
16 
17 int z;
18 const int C1 = 1;
19 const int C2 = 2;
20 void test_linear_colons()
21 {
22   int B = 0;
23   #pragma omp taskloop simd linear(B:bfoo())
24   for (int i = 0; i < 10; ++i) ;
25   // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
26   #pragma omp taskloop simd linear(B::ib:B:bfoo())
27   for (int i = 0; i < 10; ++i) ;
28   // expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
29   #pragma omp taskloop simd linear(B:ib)
30   for (int i = 0; i < 10; ++i) ;
31   // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
32   #pragma omp taskloop simd linear(z:B:ib)
33   for (int i = 0; i < 10; ++i) ;
34   #pragma omp taskloop simd linear(B:B::bfoo())
35   for (int i = 0; i < 10; ++i) ;
36   #pragma omp taskloop simd linear(X::x : ::z)
37   for (int i = 0; i < 10; ++i) ;
38   #pragma omp taskloop simd linear(B,::z, X::x)
39   for (int i = 0; i < 10; ++i) ;
40   #pragma omp taskloop simd linear(::z)
41   for (int i = 0; i < 10; ++i) ;
42   // expected-error@+1 {{expected variable name}}
43   #pragma omp taskloop simd linear(B::bfoo())
44   for (int i = 0; i < 10; ++i) ;
45   #pragma omp taskloop simd linear(B::ib,B:C1+C2)
46   for (int i = 0; i < 10; ++i) ;
47 }
48 
49 template<int L, class T, class N> T test_template(T* arr, N num) {
50   N i;
51   T sum = (T)0;
52   T ind2 = - num * L; // expected-note {{'ind2' defined here}}
53   // expected-error@+1 {{argument of a linear clause should be of integral or pointer type}}
54 #pragma omp taskloop simd linear(ind2:L)
55   for (i = 0; i < num; ++i) {
56     T cur = arr[(int)ind2];
57     ind2 += L;
58     sum += cur;
59   }
60   return T();
61 }
62 
63 template<int LEN> int test_warn() {
64   int ind2 = 0;
65   // expected-warning@+1 {{zero linear step (ind2 should probably be const)}}
66   #pragma omp taskloop simd linear(ind2:LEN)
67   for (int i = 0; i < 100; i++) {
68     ind2 += LEN;
69   }
70   return ind2;
71 }
72 
73 struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
74 extern S1 a;
75 class S2 {
76   mutable int a;
77 public:
78   S2():a(0) { }
79 };
80 const S2 b; // expected-note 2 {{'b' defined here}}
81 const S2 ba[5];
82 class S3 {
83   int a;
84 public:
85   S3():a(0) { }
86 };
87 const S3 ca[5];
88 class S4 {
89   int a;
90   S4();
91 public:
92   S4(int v):a(v) { }
93 };
94 class S5 {
95   int a;
96   S5():a(0) {}
97 public:
98   S5(int v):a(v) { }
99 };
100 
101 S3 h;
102 #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
103 
104 template<class I, class C> int foomain(I argc, C **argv) {
105   I e(4);
106   I g(5);
107   int i;
108   int &j = i;
109   #pragma omp taskloop simd linear // expected-error {{expected '(' after 'linear'}}
110   for (int k = 0; k < argc; ++k) ++k;
111   #pragma omp taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
112   for (int k = 0; k < argc; ++k) ++k;
113   #pragma omp taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
114   for (int k = 0; k < argc; ++k) ++k;
115   #pragma omp taskloop simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
116   for (int k = 0; k < argc; ++k) ++k;
117   #pragma omp taskloop simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
118   for (int k = 0; k < argc; ++k) ++k;
119   #pragma omp taskloop simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
120   for (int k = 0; k < argc; ++k) ++k;
121   #pragma omp taskloop simd linear () // expected-error {{expected expression}}
122   for (int k = 0; k < argc; ++k) ++k;
123   #pragma omp taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
124   for (int k = 0; k < argc; ++k) ++k;
125   #pragma omp taskloop simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
126   for (int k = 0; k < argc; ++k) ++k;
127   #pragma omp taskloop simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
128   for (int k = 0; k < argc; ++k) ++k;
129   #pragma omp taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
130   for (int k = 0; k < argc; ++k) ++k;
131   #pragma omp taskloop simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
132   for (int k = 0; k < argc; ++k) ++k;
133   #pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
134   for (int k = 0; k < argc; ++k) ++k;
135   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
136   // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
137   #pragma omp taskloop simd linear (val(a, b):B::ib)
138   for (int k = 0; k < argc; ++k) ++k;
139   #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
140   for (int k = 0; k < argc; ++k) ++k;
141   #pragma omp taskloop simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}}
142   for (int k = 0; k < argc; ++k) ++k;
143   #pragma omp taskloop simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
144   for (int k = 0; k < argc; ++k) ++k;
145   #pragma omp taskloop simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
146   for (int k = 0; k < argc; ++k) ++k;
147   #pragma omp parallel
148   {
149     int v = 0;
150     int i;
151     #pragma omp taskloop simd linear(v:i)
152     for (int k = 0; k < argc; ++k) { i = k; v += i; }
153   }
154   #pragma omp taskloop simd linear(ref(j))
155   for (int k = 0; k < argc; ++k) ++k;
156   #pragma omp taskloop simd linear(uval(j))
157   for (int k = 0; k < argc; ++k) ++k;
158   int v = 0;
159   #pragma omp taskloop simd linear(v:j)
160   for (int k = 0; k < argc; ++k) { ++k; v += j; }
161   #pragma omp taskloop simd linear(i)
162   for (int k = 0; k < argc; ++k) ++k;
163   return 0;
164 }
165 
166 namespace A {
167 double x;
168 #pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
169 }
170 namespace C {
171 using A::x;
172 }
173 
174 void linear_modifiers(int argc) {
175   int &f = argc;
176   #pragma omp taskloop simd linear(f)
177   for (int k = 0; k < argc; ++k) ++k;
178   #pragma omp taskloop simd linear(val(f))
179   for (int k = 0; k < argc; ++k) ++k;
180   #pragma omp taskloop simd linear(uval(f))
181   for (int k = 0; k < argc; ++k) ++k;
182   #pragma omp taskloop simd linear(ref(f))
183   for (int k = 0; k < argc; ++k) ++k;
184   #pragma omp taskloop simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}}
185   for (int k = 0; k < argc; ++k) ++k;
186 }
187 
188 int f;
189 int main(int argc, char **argv) {
190   double darr[100];
191   // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
192   test_template<-4>(darr, 4);
193   // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
194   test_warn<0>();
195 
196   S4 e(4); // expected-note {{'e' defined here}}
197   S5 g(5); // expected-note {{'g' defined here}}
198   int i;
199   int &j = i;
200   #pragma omp taskloop simd linear(f) linear(f) // expected-error {{linear variable cannot be linear}} expected-note {{defined as linear}}
201   for (int k = 0; k < argc; ++k) ++k;
202   #pragma omp taskloop simd linear // expected-error {{expected '(' after 'linear'}}
203   for (int k = 0; k < argc; ++k) ++k;
204   #pragma omp taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
205   for (int k = 0; k < argc; ++k) ++k;
206   #pragma omp taskloop simd linear () // expected-error {{expected expression}}
207   for (int k = 0; k < argc; ++k) ++k;
208   #pragma omp taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
209   for (int k = 0; k < argc; ++k) ++k;
210   #pragma omp taskloop simd linear (ref()) // expected-error {{expected expression}}
211   for (int k = 0; k < argc; ++k) ++k;
212   #pragma omp taskloop simd linear (foo()) // expected-error {{expected expression}}
213   for (int k = 0; k < argc; ++k) ++k;
214   #pragma omp taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
215   for (int k = 0; k < argc; ++k) ++k;
216   #pragma omp taskloop simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
217   for (int k = 0; k < argc; ++k) ++k;
218   #pragma omp taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
219   for (int k = 0; k < argc; ++k) ++k;
220   #pragma omp taskloop simd linear (argc)
221   for (int k = 0; k < argc; ++k) ++k;
222   #pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
223   for (int k = 0; k < argc; ++k) ++k;
224   // expected-error@+2 {{linear variable with incomplete type 'S1'}}
225   // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
226   #pragma omp taskloop simd linear(a, b)
227   for (int k = 0; k < argc; ++k) ++k;
228   #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
229   for (int k = 0; k < argc; ++k) ++k;
230   // expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}}
231   // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
232   #pragma omp taskloop simd linear(val(e, g))
233   for (int k = 0; k < argc; ++k) ++k;
234   #pragma omp taskloop simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
235   for (int k = 0; k < argc; ++k) ++k;
236   #pragma omp parallel
237   {
238     int i;
239     #pragma omp taskloop simd linear(val(i))
240     for (int k = 0; k < argc; ++k) ++k;
241     #pragma omp taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
242     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
243   }
244   #pragma omp taskloop simd linear(ref(j))
245   for (int k = 0; k < argc; ++k) ++k;
246   #pragma omp taskloop simd linear(i)
247   for (int k = 0; k < argc; ++k) ++k;
248 
249   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
250   return 0;
251 }
252 
253