blob: dc721ce10fd44dca324cd3d2d1662a1cd70a28a2 [file] [log] [blame]
Larisse Voufo39a1e502013-08-06 01:03:05 +00001// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s
2// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s -DCXX11
3// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -DCXX11
4
5#ifdef CXX11
6 #define CONST constexpr
7#else
8 #define CONST const
9#endif
10
11template<typename T>
12T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
13
14template<typename T>
15CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
16
Larisse Voufoa11bd8a2013-08-13 02:02:26 +000017template<typename T> extern CONST T vc;
18#ifdef CXX11
19// expected-error@-2 {{constexpr variable declaration must be a definition}}
20#endif
21
Larisse Voufo39a1e502013-08-06 01:03:05 +000022namespace use_in_top_level_funcs {
23
24 void good() {
25 int ipi = pi<int>;
26 int icpi = cpi<int>;
27 double dpi = pi<double>;
28 double dcpi = cpi<double>;
29 }
30
31 void no_deduce() {
32 // template arguments are not deduced for uses of variable templates.
33 int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}}
34 int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}}
35 }
36
37 template<typename T>
38 T circular_area(T r) {
39 return pi<T> * r * r;
40 }
41
42 template<typename T>
43 CONST T const_circular_area(T r) {
44 return cpi<T> * r * r;
45 }
46
47 double use_circular_area(double r) {
48 CONST float t = const_circular_area(2.0) - 12;
49#ifdef CXX11
50 static_assert(const_circular_area(2) == 12, "");
51 CONST int test = (t > 0) && (t < 1);
52 static_assert(test, "");
53#endif
54 return circular_area(r);
55 }
56}
57
58namespace shadow {
59 void foo() {
60 int ipi0 = pi<int>;
61 int pi;
62 int a = pi;
63 int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
64 // expected-error {{expected expression}}
65 }
66}
67
68namespace odr_tmpl {
69 namespace pv_cvt {
70 int v; // expected-note {{previous definition is here}}
71 template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}}
72 }
73 namespace pvt_cv {
74 template<typename T> T v; // expected-note {{previous definition is here}}
75 int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
76 }
77 namespace pvt_cvt {
78 template<typename T> T v0; // expected-note {{previous definition is here}}
79 template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
80
81 template<typename T> T v; // expected-note {{previous definition is here}}
82 template<typename T> int v; // expected-error {{redefinition of 'v'}}
83
84 template<typename T> int v1; // expected-note {{previous template declaration is here}}
85 template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
86 }
87 namespace pvt_use {
88 template<typename T> T v;
89 v = 10; // expected-error {{C++ requires a type specifier for all declarations}}
90 }
91
92 namespace pvt_diff_params {
93 // FIXME: (?) Redefinitions should simply be not allowed, whether the
94 // template parameters match or not. However, this current behaviour also
95 // matches that of class templates...
96 template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
97 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
98 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
99 }
100
101 namespace pvt_extern {
102 template<typename T> T v = T();
103 template<typename T> extern T v; // redeclaration is allowed \
104 // expected-note {{previous definition is here}}
105 template<typename T> extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
106
107#ifdef CXX11
108 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
109#endif
110 }
111
112#ifdef CXX11
113 namespace pvt_auto {
114 template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
115 template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
116 template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
117 template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
118 template<typename T> T v2; // expected-error {{redefinition of 'v2'}}
119 template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
120 template<typename T> extern T v3; // expected-error {{redefinition of 'v3' with a different type: 'T' vs 'auto'}}
121 template<typename T> auto v4 = T();
122 template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
123 }
124#endif
125
126}
127
128namespace explicit_instantiation {
129 template<typename T>
130 T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
131 template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
132
133 template<typename T>
134 T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
135 template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
136
137 template<typename T>
138 T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
139 template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
140
141 template<typename T>
142 T pi0 = T(3.1415926535897932385);
143 template int pi0<int>; // expected-note {{previous explicit instantiation is here}}
144 template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
145
146 template<typename T>
147 CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
148 template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
149
150 template<typename T>
151 CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
152 template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
153
154 template<typename T>
155 CONST T pi1 = T(3.1415926535897932385);
156 template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}}
157 template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
158
159#ifdef CXX11
160 namespace auto_var {
161 template<typename T> auto var0 = T();
162 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
163
164 template<typename T> auto var = T();
165 template int var<int>;
166 }
167#endif
168
169 namespace extern_var {
170 // TODO:
171 }
172}
173
174namespace explicit_specialization {
175
176 namespace good {
177 template<typename T1, typename T2>
178 CONST int pi2 = 1;
179
180 template<typename T>
181 CONST int pi2<T,int> = 2;
182
183 template<typename T>
184 CONST int pi2<int,T> = 3;
185
186 template<> CONST int pi2<int,int> = 4;
187
188#ifdef CXX11
189 void foo() {
190 static_assert(pi2<int,int> == 4, "");
191 static_assert(pi2<float,int> == 2, "");
192 static_assert(pi2<int,float> == 3, "");
193 static_assert(pi2<int,float> == pi2<int,double>, "");
194 static_assert(pi2<float,float> == 1, "");
195 static_assert(pi2<float,float> == pi2<float,double>, "");
196 }
197#endif
198 }
199
200 namespace ambiguous {
201
202 template<typename T1, typename T2>
203 CONST int pi2 = 1;
204
205 template<typename T>
206 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
207
208 template<typename T>
209 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
210
211 void foo() {
212 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
213 }
214 }
215
216 namespace type_changes {
217
218 template<typename T>
219 T pi0 = T(3.1415926535897932385);
220
221 template<> float pi0<int> = 10;
222 template<> int pi0<const int> = 10;
223
224 template<typename T>
225 T pi1 = T(3.1415926535897932385);
226 template<> CONST int pi1<int> = 10;
227
228 template<typename T>
229 T pi2 = T(3.1415926535897932385);
230 template<> int pi2<const int> = 10;
231
232 template<typename T>
233 CONST T pi4 = T(3.1415926535897932385);
234 template<> int pi4<int> = 10;
235 }
236
237 namespace redefinition {
238 template<typename T>
239 T pi0 = T(3.1415926535897932385);
240
241 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
242#ifdef CXX11
243// expected-note@-2 {{previous definition is here}}
244#endif
245 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
246 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
247 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
248#ifdef CXX11
249 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
250#endif
251
252
253 template<typename T>
254 CONST T pi1 = T(3.1415926535897932385);
255
256 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
257 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
258 }
259
260 namespace before_instantiation {
261 template<typename T>
262 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
263
264 template<> int pi0<int> = 10;
265 template int pi0<int>;
266 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
267
268 template<typename T1, typename T2>
269 CONST int pi2 = 1;
270
271 template<typename T> CONST int pi2<T,int> = 2;
272 template CONST int pi2<int,int>;
273 }
274 namespace after_instantiation {
275 template<typename T>
276 T pi0 = T(3.1415926535897932385);
277
278 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
279 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
280 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
281
282 template<typename T1, typename T2>
283 CONST int pi2 = 1;
284
285 template CONST int pi2<int,int>;
286 template<typename T> CONST int pi2<T,int> = 2;
287 }
288
289#ifdef CXX11
290 namespace auto_var {
291 template<typename T, typename> auto var0 = T();
292 template<typename T> auto var0<T,int> = T();
293 template<> auto var0<int,int> = 7;
294
295 template<typename T, typename> auto var = T();
296 template<typename T> T var<T,int> = T(5);
297 template<> int var<int,int> = 7;
298
299 void foo() {
300 int i0 = var0<int,int>;
301 int b = var<int,int>;
302 }
303 }
304#endif
305
306 namespace extern_var {
307 // TODO:
308 }
309
310 namespace diff_type {
311 // TODO:
312 template<typename T> T var = T();
313 template<typename T> T* var<T> = new T();
314#ifdef CXX11
315 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
316 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
317#endif
318 }
319}
320
321namespace use_in_structs {
322 // TODO:
323}
324
325namespace attributes {
326 // TODO:
327}
328
329#ifdef CXX11
330namespace arrays {
331 template<typename T>
332 T* arr = new T[10]{T(10), T(23)};
333
334 float f = 10.5;
335 template<> float* arr<float> = &f;
336
337 void bar() {
338 int *iarr = arr<int>;
339 iarr[0] = 1;
340 iarr[2] = 3;
341 iarr[6] = -2;
342
343 float ff = *arr<float>;
344 float nof = arr<float>[3]; // No bounds-check in C++
345 }
346}
347#endif
348
349namespace nested {
350
351 namespace n0a {
352 template<typename T>
353 T pi0a = T(3.1415926535897932385);
354 }
355
356 using namespace n0a;
357 int i0a = pi0a<int>;
358
359 template float pi0a<float>;
360 float f0a = pi0a<float>;
361
362 template<> double pi0a<double> = 5.2;
363 double d0a = pi0a<double>;
364
365 namespace n0b {
366 template<typename T>
367 T pi0b = T(3.1415926535897932385);
368 }
369
370 int i0b = n0b::pi0b<int>;
371
372 template float n0b::pi0b<float>;
373 float f0b = n0b::pi0b<float>;
374
375 template<> double n0b::pi0b<double> = 5.2;
376 double d0b = n0b::pi0b<double>;
377
378 namespace n1 {
379 template<typename T>
380 T pi1a = T(3.1415926535897932385);
381#ifdef CXX11
382// expected-note@-2 {{explicit instantiation refers here}}
383#endif
384
385 template<typename T>
386 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
387#ifdef CXX11
388// expected-note@-2 {{explicit instantiation refers here}}
389#endif
390 }
391
392 namespace use_n1a {
393 using namespace n1;
394 int i1 = pi1a<int>;
395
396 template float pi1a<float>;
397#ifdef CXX11
398// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
399#endif
400 float f1 = pi1a<float>;
401
402 template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
403 double d1 = pi1a<double>;
404 }
405
406 namespace use_n1b {
407 int i1 = n1::pi1b<int>;
408
409 template float n1::pi1b<float>;
410#ifdef CXX11
411// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
412#endif
413 float f1 = n1::pi1b<float>;
414
415 template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
416 // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
417 double d1 = n1::pi1b<double>;
418 }
419}
420