1 // RUN: %clang_cc1 %s -verify -fopenacc
2
3 struct Incomplete; // #INCOMPLETE
4 struct NotConvertible{} NC;
5
6 struct CorrectConvert {
7 operator int();
8 } Convert;
9
returns_3()10 constexpr int returns_3() { return 3; }
11
12 using FuncPtrTy = void (*)();
13 FuncPtrTy FuncPtrTyArray[2];
14
Func(int i,int j)15 void Func(int i, int j) {
16 int array[5];
17 int VLA[i];
18 int *ptr;
19 void *void_ptr;
20
21 // Follows int-expr rules, so only convertible to int.
22 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
23 #pragma acc parallel private(array[NC:])
24 while (true);
25
26 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
27 #pragma acc parallel private(array[:NC])
28 while (true);
29
30 // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
31 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
32 #pragma acc parallel private(array[NC:NC])
33 while (true);
34
35 // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
36 // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
37 #pragma acc parallel private(ptr[NC:])
38 while (true);
39
40 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
41 #pragma acc parallel private(ptr[:NC])
42 while (true);
43
44 // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
45 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}}
46 #pragma acc parallel private(ptr[NC:NC])
47 while (true);
48
49 // These are convertible, so they work.
50 #pragma acc parallel private(array[Convert:Convert])
51 while (true);
52
53 #pragma acc parallel private(ptr[Convert:Convert])
54 while (true);
55
56
57 // The length for "dynamically" allocated dimensions of an array must be
58 // explicitly specified.
59
60 // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
61 #pragma acc parallel private(ptr[3:])
62 while (true);
63
64 // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
65 #pragma acc parallel private(VLA[3:])
66 while (true);
67
68 #pragma acc parallel private(ptr[:3])
69 while (true);
70
71 #pragma acc parallel private(VLA[:3])
72 while (true);
73
74 // Error if the length of the array + the initializer is bigger the the array
75 // with known bounds.
76
77 // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}}
78 #pragma acc parallel private(array[i:returns_3() + 3])
79 while (true);
80
81 // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}}
82 #pragma acc parallel private(array[:returns_3() + 3])
83 while (true);
84
85 #pragma acc parallel private(array[:returns_3()])
86 while (true);
87
88 // expected-error@+1{{OpenACC sub-array specified range [3:3] would be out of the range of the subscripted array size of 5}}
89 #pragma acc parallel private(array[returns_3():returns_3()])
90 while (true);
91
92 // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (6) that would be out of the range of the subscripted array size of 5}}
93 #pragma acc parallel private(array[returns_3() + 3:])
94 while (true);
95
96 // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (6) that would be out of the range of the subscripted array size of 5}}
97 #pragma acc parallel private(array[returns_3() + 3:1])
98 while (true);
99
100 // Standard doesn't specify this, but negative values are likely not
101 // permitted, so disallow them here until we come up with a good reason to do
102 // otherwise.
103
104 // expected-error@+1{{OpenACC sub-array lower bound evaluated to negative value -1}}
105 #pragma acc parallel private(array[returns_3() - 4 : ])
106 while (true);
107
108 // expected-error@+1{{OpenACC sub-array length evaluated to negative value -1}}
109 #pragma acc parallel private(array[: -1])
110 while (true);
111
112 Incomplete *IncompletePtr;
113 // expected-error@+2{{OpenACC sub-array base is of incomplete type 'Incomplete'}}
114 // expected-note@#INCOMPLETE{{forward declaration of 'Incomplete'}}
115 #pragma acc parallel private(IncompletePtr[0 :1])
116 while (true);
117
118 // expected-error@+1{{OpenACC sub-array base is of incomplete type 'void'}}
119 #pragma acc parallel private(void_ptr[0:1])
120 while (true);
121
122 // OK: these are function pointers.
123 #pragma acc parallel private(FuncPtrTyArray[0 :1])
124 while (true);
125
126 // expected-error@+1{{OpenACC sub-array cannot be of function type 'void ()'}}
127 #pragma acc parallel private(FuncPtrTyArray[0][0 :1])
128 while (true);
129
130
131 // expected-error@+1{{OpenACC sub-array subscripted value is not an array or pointer}}
132 #pragma acc parallel private(i[0:1])
133 while (true);
134 }
135
136 template<typename T, typename U, typename V, unsigned I, auto &CEArray>
Templ(int i)137 void Templ(int i){
138 T array[I];
139 T VLA[i];
140 T *ptr;
141 U NC;
142 V Conv;
143
144 // Convertible:
145 // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('NotConvertible' invalid}}
146 // expected-note@#INST{{in instantiation of function template specialization}}
147 #pragma acc parallel private(array[NC:])
148 while (true);
149 // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('NotConvertible' invalid}}
150 #pragma acc parallel private(array[:NC])
151 while (true);
152
153 #pragma acc parallel private(array[Conv:])
154 while (true);
155 #pragma acc parallel private(array[:Conv])
156 while (true);
157
158 // Need a length for unknown size.
159 // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
160 #pragma acc parallel private(ptr[Conv:])
161 while (true);
162 // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}}
163 #pragma acc parallel private(VLA[Conv:])
164 while (true);
165 #pragma acc parallel private(ptr[:Conv])
166 while (true);
167 #pragma acc parallel private(VLA[:Conv])
168 while (true);
169
170 // Out of bounds.
171 // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (2) that would be out of the range of the subscripted array size of 2}}
172 #pragma acc parallel private(array[I:])
173 while (true);
174
175 // OK, don't know the value.
176 #pragma acc parallel private(array[i:])
177 while (true);
178
179 // expected-error@+1{{OpenACC sub-array length evaluated to a value (3) that would be out of the range of the subscripted array size of 2}}
180 #pragma acc parallel private(array[:I + 1])
181 while (true);
182
183 // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (5) that would be out of the range of the subscripted array size of 5}}
184 #pragma acc parallel private(CEArray[5:])
185 while (true);
186
187 // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}}
188 #pragma acc parallel private(CEArray[:2 + I + I])
189 while (true);
190
191 // expected-error@+1{{OpenACC sub-array length evaluated to a value (4294967295) that would be out of the range of the subscripted array size of 5}}
192 #pragma acc parallel private(CEArray[:1 - I])
193 while (true);
194
195 // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (4294967295) that would be out of the range of the subscripted array size of 5}}
196 #pragma acc parallel private(CEArray[1 - I:])
197 while (true);
198
199 T not_ptr;
200 // expected-error@+1{{OpenACC sub-array subscripted value is not an array or pointer}}
201 #pragma acc parallel private(not_ptr[0:1])
202 while (true);
203 }
204
inst()205 void inst() {
206 static constexpr int CEArray[5]={1,2,3,4,5};
207 Templ<int, NotConvertible, CorrectConvert, 2, CEArray>(5); // #INST
208 }
209