1 // RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
2 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
3 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
8 #define CONST constexpr
12 T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
15 CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
17 template<typename T> extern CONST T vc;
19 // expected-error@-2 {{constexpr variable declaration must be a definition}}
22 namespace use_in_top_level_funcs {
27 double dpi = pi<double>;
28 double dcpi = cpi<double>;
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}}
38 T circular_area(T r) {
43 CONST T const_circular_area(T r) {
44 return cpi<T> * r * r;
47 double use_circular_area(double r) {
48 CONST float t = const_circular_area(2.0) - 12;
50 static_assert(const_circular_area(2) == 12, "");
51 CONST int test = (t > 0) && (t < 1);
52 static_assert(test, "");
54 return circular_area(r);
63 int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
64 // expected-error {{expected expression}}
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}}
74 template<typename T> T v; // expected-note {{previous definition is here}}
75 int v; // expected-error {{redefinition of 'v' as different kind of symbol}}
78 template<typename T> T v0; // expected-note {{previous definition is here}}
79 template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
81 template<typename T> T v; // expected-note {{previous definition is here}}
82 template<typename T> int v; // expected-error {{redefinition of 'v'}}
84 template<typename T> extern 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}}
88 template<typename T> T v;
89 v = 10; // expected-error {{C++ requires a type specifier for all declarations}}
92 namespace pvt_diff_params {
93 template<typename T, typename> T v; // expected-note {{previous template declaration is here}}
94 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
95 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
98 namespace pvt_extern {
99 template<typename T> T v = T();
100 template<typename T> extern T v; // redeclaration is allowed \
101 // expected-note {{previous declaration is here}}
102 template<typename T> extern int v; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
105 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
108 template<typename T> T var = T(); // expected-note {{previous definition is here}}
109 extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}}
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 {{redeclaration 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}}
128 namespace explicit_instantiation {
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'}}
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'}}
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'}}
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>'}}
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'}}
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'}}
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>'}}
161 template<typename T> auto var0 = T();
162 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
164 template<typename T> auto var = T();
165 template int var<int>;
169 template<typename=int> int missing_args; // expected-note {{here}}
170 template int missing_args; // expected-error {{must specify a template argument list}}
172 namespace extern_var {
177 namespace explicit_specialization {
180 template<typename T1, typename T2>
184 CONST int pi2<T,int> = 2;
187 CONST int pi2<int,T> = 3;
189 template<> CONST int pi2<int,int> = 4;
193 static_assert(pi2<int,int> == 4, "");
194 static_assert(pi2<float,int> == 2, "");
195 static_assert(pi2<int,float> == 3, "");
196 static_assert(pi2<int,float> == pi2<int,double>, "");
197 static_assert(pi2<float,float> == 1, "");
198 static_assert(pi2<float,float> == pi2<float,double>, "");
203 namespace ambiguous {
205 template<typename T1, typename T2>
209 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
212 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
215 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
219 namespace type_changes {
222 T pi0 = T(3.1415926535897932385);
224 template<> float pi0<int> = 10;
225 template<> int pi0<const int> = 10;
228 T pi1 = T(3.1415926535897932385);
229 template<> CONST int pi1<int> = 10;
232 T pi2 = T(3.1415926535897932385);
233 template<> int pi2<const int> = 10;
236 CONST T pi4 = T(3.1415926535897932385);
237 template<> int pi4<int> = 10;
240 namespace redefinition {
242 T pi0 = T(3.1415926535897932385);
244 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
246 // expected-note@-2 {{previous definition is here}}
248 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
249 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
250 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
252 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
257 CONST T pi1 = T(3.1415926535897932385);
259 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
260 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
263 namespace before_instantiation {
265 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
267 template<> int pi0<int> = 10;
268 template int pi0<int>;
269 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
271 template<typename T1, typename T2>
274 template<typename T> CONST int pi2<T,int> = 2;
275 template CONST int pi2<int,int>;
277 namespace after_instantiation {
279 T pi0 = T(3.1415926535897932385);
281 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
282 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
283 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
285 template<typename T1, typename T2>
288 template CONST int pi2<int,int>;
289 template<typename T> CONST int pi2<T,int> = 2;
294 template<typename T, typename> auto var0 = T();
295 template<typename T> auto var0<T,int> = T();
296 template<> auto var0<int,int> = 7;
298 template<typename T, typename> auto var = T();
299 template<typename T> T var<T,int> = T(5);
300 template<> int var<int,int> = 7;
303 int i0 = var0<int,int>;
304 int b = var<int,int>;
309 namespace extern_var {
313 namespace diff_type {
315 template<typename T> T* var = new T();
317 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
318 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
323 namespace narrowing {
324 template<typename T> T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
326 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
327 // expected-note@-2 {{insert an explicit cast to silence this issue}}
329 int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
332 namespace use_in_structs {
336 namespace attributes {
343 T* arr = new T[10]{T(10), T(23)};
346 template<> float* arr<float> = &f;
349 int *iarr = arr<int>;
354 float ff = *arr<float>;
355 float nof = arr<float>[3]; // No bounds-check in C++
364 T pi0a = T(3.1415926535897932385);
370 template float pi0a<float>;
371 float f0a = pi0a<float>;
373 template<> double pi0a<double> = 5.2;
374 double d0a = pi0a<double>;
378 T pi0b = T(3.1415926535897932385);
381 int i0b = n0b::pi0b<int>;
383 template float n0b::pi0b<float>;
384 float f0b = n0b::pi0b<float>;
386 template<> double n0b::pi0b<double> = 5.2;
387 double d0b = n0b::pi0b<double>;
391 T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
393 // expected-note@-2 {{explicit instantiation refers here}}
397 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
399 // expected-note@-2 {{explicit instantiation refers here}}
407 template float pi1a<float>;
409 // expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
411 float f1 = pi1a<float>;
413 template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
414 double d1 = pi1a<double>;
418 int i1 = n1::pi1b<int>;
420 template float n1::pi1b<float>;
422 // expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
424 float f1 = n1::pi1b<float>;
426 template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
427 // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
428 double d1 = n1::pi1b<double>;
432 namespace nested_name {
433 template<typename T> int a; // expected-note {{variable template 'a' declared here}}
434 a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
436 class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
437 enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
441 template<typename T> int a;
442 int a<int>; // expected-error {{requires 'template<>'}}
447 template<typename T> const auto x = 1;
448 static_assert(x<int> == 1, "");
453 template <typename T> int* f();
454 template <typename T> void f();
455 template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
457 template <typename T> void g();
458 template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}