1// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s
2
3struct B {
4  static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
5  static constexpr int bfoo() { return 8; }
6};
7namespace X {
8  B x; // expected-note {{'x' defined here}}
9};
10constexpr int bfoo() { return 4; }
11
12int **z;
13const int C1 = 1;
14const int C2 = 2;
15void test_aligned_colons(int *&rp)
16{
17  int *B = 0;
18  #pragma omp for simd aligned(B:bfoo())
19  for (int i = 0; i < 10; ++i) ;
20  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
21  #pragma omp for simd aligned(B::ib:B:bfoo())
22  for (int i = 0; i < 10; ++i) ;
23  #pragma omp for simd aligned(B: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 for simd aligned(z:B:bfoo())
27  for (int i = 0; i < 10; ++i) ;
28  #pragma omp for simd aligned(B:B::bfoo())
29  for (int i = 0; i < 10; ++i) ;
30  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
31  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
32  #pragma omp for simd aligned(X::x : ::z)
33  for (int i = 0; i < 10; ++i) ;
34  // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
35  #pragma omp for simd aligned(B,rp,::z: X::x)
36  for (int i = 0; i < 10; ++i) ;
37  #pragma omp for simd aligned(::z)
38  for (int i = 0; i < 10; ++i) ;
39  // expected-error@+1 {{expected variable name}}
40  #pragma omp for simd aligned(B::bfoo())
41  for (int i = 0; i < 10; ++i) ;
42  // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}}
43  #pragma omp for simd aligned(B::ib,B:C1+C2)
44  for (int i = 0; i < 10; ++i) ;
45}
46
47// expected-note@+1 {{'num' defined here}}
48template<int L, class T, class N> T test_template(T* arr, N num) {
49  N i;
50  T sum = (T)0;
51  T ind2 = - num * L;
52  // Negative number is passed as L.
53  // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}}
54  #pragma omp for simd aligned(arr:L)
55  for (i = 0; i < num; ++i) {
56    T cur = arr[(int)ind2];
57    ind2 += L;
58    sum += cur;
59  }
60  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
61  #pragma omp for simd aligned(num:4)
62  for (i = 0; i < num; ++i);
63  return T();
64}
65
66template<int LEN> int test_warn() {
67  int *ind2 = 0;
68  // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}}
69  #pragma omp for simd aligned(ind2:LEN)
70  for (int i = 0; i < 100; i++) {
71    ind2 += LEN;
72  }
73  return 0;
74}
75
76struct S1; // expected-note 2 {{declared here}}
77extern S1 a; // expected-note {{'a' declared here}}
78class S2 {
79  mutable int a;
80public:
81  S2():a(0) { }
82};
83const S2 b; // expected-note 1 {{'b' defined here}}
84const S2 ba[5];
85class S3 {
86  int a;
87public:
88  S3():a(0) { }
89};
90const S3 ca[5];
91class S4 {
92  int a;
93  S4();
94public:
95  S4(int v):a(v) { }
96};
97class S5 {
98  int a;
99  S5():a(0) {}
100public:
101  S5(int v):a(v) { }
102};
103
104S3 h; // expected-note 2 {{'h' defined here}}
105#pragma omp threadprivate(h)
106
107template<class I, class C> int foomain(I argc, C **argv) {
108  I e(argc);
109  I g(argc);
110  int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
111  // expected-note@+2 {{declared here}}
112  // expected-note@+1 {{reference to 'i' is not a constant expression}}
113  int &j = i;
114  #pragma omp for simd aligned // expected-error {{expected '(' after 'aligned'}}
115  for (I k = 0; k < argc; ++k) ++k;
116  #pragma omp for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
117  for (I k = 0; k < argc; ++k) ++k;
118  #pragma omp for simd aligned () // expected-error {{expected expression}}
119  for (I k = 0; k < argc; ++k) ++k;
120  #pragma omp for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
121  for (I k = 0; k < argc; ++k) ++k;
122  #pragma omp for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
123  for (I k = 0; k < argc; ++k) ++k;
124  #pragma omp for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
125  for (I k = 0; k < argc; ++k) ++k;
126  #pragma omp for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
127  for (I k = 0; k < argc; ++k) ++k;
128  #pragma omp for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
129  for (I k = 0; k < argc; ++k) ++k;
130  #pragma omp for simd aligned (argv[1]) // expected-error {{expected variable name}}
131  for (I k = 0; k < argc; ++k) ++k;
132  #pragma omp for simd aligned(e, g)
133  for (I k = 0; k < argc; ++k) ++k;
134  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
135  #pragma omp for simd aligned(h)
136  for (I k = 0; k < argc; ++k) ++k;
137  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
138  #pragma omp for simd aligned(i)
139  for (I k = 0; k < argc; ++k) ++k;
140  #pragma omp parallel
141  {
142    int *v = 0;
143    I i;
144    #pragma omp for simd aligned(v:16)
145    for (I k = 0; k < argc; ++k) { i = k; v += 2; }
146  }
147  float *f;
148  #pragma omp for simd aligned(f)
149  for (I k = 0; k < argc; ++k) ++k;
150  int v = 0;
151  // expected-note@+2 {{initializer of 'j' is not a constant expression}}
152  // expected-error@+1 {{expression is not an integral constant expression}}
153  #pragma omp for simd aligned(f:j)
154  for (I k = 0; k < argc; ++k) { ++k; v += j; }
155  #pragma omp for simd aligned(f)
156  for (I k = 0; k < argc; ++k) ++k;
157  return 0;
158}
159
160// expected-note@+1 2 {{'argc' defined here}}
161int main(int argc, char **argv) {
162  double darr[100];
163  // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
164  test_template<-4>(darr, 4);
165  test_warn<4>(); // ok
166  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
167  test_warn<0>();
168
169  int i;
170  int &j = i;
171  #pragma omp for simd aligned // expected-error {{expected '(' after 'aligned'}}
172  for (int k = 0; k < argc; ++k) ++k;
173  #pragma omp for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
174  for (int k = 0; k < argc; ++k) ++k;
175  #pragma omp for simd aligned () // expected-error {{expected expression}}
176  for (int k = 0; k < argc; ++k) ++k;
177  #pragma omp for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
178  for (int k = 0; k < argc; ++k) ++k;
179  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
180  #pragma omp for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
181  for (int k = 0; k < argc; ++k) ++k;
182  #pragma omp for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
183  for (int k = 0; k < argc; ++k) ++k;
184  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
185  #pragma omp for simd aligned (argc)
186  for (int k = 0; k < argc; ++k) ++k;
187  #pragma omp for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
188  for (int k = 0; k < argc; ++k) ++k;
189  // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
190  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
191  #pragma omp for simd aligned (a, b)
192  for (int k = 0; k < argc; ++k) ++k;
193  #pragma omp for simd aligned (argv[1]) // expected-error {{expected variable name}}
194  for (int k = 0; k < argc; ++k) ++k;
195  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
196  #pragma omp for simd aligned(h)
197  for (int k = 0; k < argc; ++k) ++k;
198  int *pargc = &argc;
199  // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
200  foomain<int*,char>(pargc,argv);
201  return 0;
202}
203
204