1 // RUN: %clang_cc1 -std=c++98 -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 2{{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 {{use of variable template 'pi' requires template arguments}}
34 int icpi
= cpi
; // expected-error {{use of variable template 'cpi' requires template arguments}}
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
);
61 int pi
; // expected-note {{found}}
63 int ipi
= pi
<int>; // expected-error {{'pi' does not name a template but is followed by template arguments; did you mean '::pi'?}}
69 int v
; // expected-note {{previous definition is here}}
70 template<typename T
> T v
; // expected-error {{redefinition of 'v' as different kind of symbol}}
73 template<typename T
> T v
; // expected-note {{previous definition is here}}
74 int v
; // expected-error {{redefinition of 'v' as different kind of symbol}}
77 template<typename T
> T v0
; // expected-note {{previous definition is here}}
78 template<typename T
> T v0
; // expected-error {{redefinition of 'v0'}}
80 template<typename T
> T v
; // expected-note {{previous definition is here}}
81 template<typename T
> int v
; // expected-error {{redefinition of 'v'}}
83 template<typename T
> extern int v1
; // expected-note {{previous template declaration is here}}
84 template<int I
> int v1
; // expected-error {{template parameter has a different kind in template redeclaration}}
87 template<typename T
> T v
;
88 v
= 10; // expected-error {{a type specifier is required for all declarations}}
91 namespace pvt_diff_params
{
92 template<typename T
, typename
> T v
; // expected-note 2{{previous template declaration is here}}
93 template<typename T
> T v
; // expected-error {{too few template parameters in template redeclaration}}
94 template<typename T
, typename
, typename
> T v
; // expected-error {{too many template parameters in template redeclaration}}
97 namespace pvt_extern
{
98 template<typename T
> T v
= T();
99 template<typename T
> extern T v
; // redeclaration is allowed \
100 // expected-note {{previous declaration is here}}
101 template<typename T
> extern int v
; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
104 template<typename T
> extern auto v
; // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}}
107 template<typename T
> T var
= T(); // expected-note {{previous definition is here}}
108 extern int var
; // expected-error {{redefinition of 'var' as different kind of symbol}}
113 template<typename T
> auto v0
; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}}
114 template<typename T
> auto v1
= T(); // expected-note {{previous definition is here}}
115 template<typename T
> int v1
; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
116 template<typename T
> auto v2
= T(); // expected-note {{previous definition is here}}
117 template<typename T
> T v2
; // expected-error {{redefinition of 'v2'}}
118 template<typename T
> auto v3
= T(); // expected-note {{previous definition is here}}
119 template<typename T
> extern T v3
; // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
120 template<typename T
> auto v4
= T();
121 template<typename T
> extern auto v4
; // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}}
127 namespace explicit_instantiation
{
129 T pi0a
= T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
130 template float pi0a
<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
133 T pi0b
= T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
134 template CONST
int pi0b
<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
137 T pi0c
= T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
138 template int pi0c
<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
141 T pi0
= T(3.1415926535897932385);
142 template int pi0
<int>; // expected-note {{previous explicit instantiation is here}}
143 template int pi0
<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
146 CONST T pi1a
= T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
147 template int pi1a
<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
150 CONST T pi1b
= T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
151 template int pi1b
<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
154 CONST T pi1
= T(3.1415926535897932385);
155 template CONST
int pi1
<int>; // expected-note {{previous explicit instantiation is here}}
156 template CONST
int pi1
<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
160 template<typename T
> auto var0
= T();
161 template auto var0
<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
163 template<typename T
> auto var
= T();
164 template int var
<int>;
168 template<typename
=int> int missing_args
; // expected-note {{here}}
169 template int missing_args
; // expected-error {{must specify a template argument list}}
171 namespace extern_var
{
176 namespace explicit_specialization
{
179 template<typename T1
, typename T2
>
183 CONST
int pi2
<T
,int> = 2;
186 CONST
int pi2
<int,T
> = 3;
188 template<> CONST
int pi2
<int,int> = 4;
192 static_assert(pi2
<int,int> == 4, "");
193 static_assert(pi2
<float,int> == 2, "");
194 static_assert(pi2
<int,float> == 3, "");
195 static_assert(pi2
<int,float> == pi2
<int,double>, "");
196 static_assert(pi2
<float,float> == 1, "");
197 static_assert(pi2
<float,float> == pi2
<float,double>, "");
202 namespace ambiguous
{
204 template<typename T1
, typename T2
>
208 CONST
int pi2
<T
,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
211 CONST
int pi2
<int,T
> = 3; // expected-note {{partial specialization matches [with T = int]}}
214 int a
= pi2
<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
218 namespace type_changes
{
221 T pi0
= T(3.1415926535897932385);
223 template<> float pi0
<int> = 10;
224 template<> int pi0
<const int> = 10;
227 T pi1
= T(3.1415926535897932385);
228 template<> CONST
int pi1
<int> = 10;
231 T pi2
= T(3.1415926535897932385);
232 template<> int pi2
<const int> = 10;
235 CONST T pi4
= T(3.1415926535897932385);
236 template<> int pi4
<int> = 10;
239 namespace redefinition
{
241 T pi0
= T(3.1415926535897932385);
243 template<> int pi0
<int> = 10; // expected-note 3{{previous definition is here}}
245 // expected-note@-2 {{previous definition is here}}
247 template<> int pi0
<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
248 template<> CONST
int pi0
<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
249 template<> float pi0
<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
251 template<> auto pi0
<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
256 CONST T pi1
= T(3.1415926535897932385);
258 template<> CONST
int pi1
<int> = 10; // expected-note {{previous definition is here}}
259 template<> CONST
int pi1
<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
262 namespace before_instantiation
{
264 T pi0
= T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
266 template<> int pi0
<int> = 10; // expected-note 2{{previous template specialization is here}}
267 template int pi0
<int>; // expected-warning {{has no effect}}
268 template float pi0
<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}}
270 template<typename T1
, typename T2
>
273 template<typename T
> CONST
int pi2
<T
,int> = 2;
274 template CONST
int pi2
<int,int>;
276 namespace after_instantiation
{
278 T pi0
= T(3.1415926535897932385);
280 template int pi0
<int>; // expected-note 2{{explicit instantiation first required here}}
281 template<> int pi0
<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
282 template<> float pi0
<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
284 template<typename T1
, typename T2
>
287 template CONST
int pi2
<int,int>;
288 template<typename T
> CONST
int pi2
<T
,int> = 2;
293 template<typename T
, typename
> auto var0
= T();
294 template<typename T
> auto var0
<T
,int> = T();
295 template<> auto var0
<int,int> = 7;
297 template<typename T
, typename
> auto var
= T();
298 template<typename T
> T var
<T
,int> = T(5);
299 template<> int var
<int,int> = 7;
302 int i0
= var0
<int,int>;
303 int b
= var
<int,int>;
308 namespace extern_var
{
312 namespace diff_type
{
314 template<typename T
> T
* var
= new T();
316 template<typename T
> auto var
<T
*> = T(); // expected-note {{previous definition is here}}
317 template<typename T
> T var
<T
*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
322 namespace narrowing
{
323 template<typename T
> T v
= {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
325 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
326 // expected-note@-2 {{insert an explicit cast to silence this issue}}
328 int k
= v
<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
331 namespace use_in_structs
{
335 namespace attributes
{
342 T
* arr
= new T
[10]{T(10), T(23)};
345 template<> float* arr
<float> = &f
;
348 int *iarr
= arr
<int>;
353 float ff
= *arr
<float>;
354 float nof
= arr
<float>[3]; // No bounds-check in C++
363 T pi0a
= T(3.1415926535897932385);
369 template float pi0a
<float>;
370 float f0a
= pi0a
<float>;
372 template<> double pi0a
<double> = 5.2;
373 double d0a
= pi0a
<double>;
377 T pi0b
= T(3.1415926535897932385);
380 int i0b
= n0b::pi0b
<int>;
382 template float n0b::pi0b
<float>;
383 float f0b
= n0b::pi0b
<float>;
385 template<> double n0b::pi0b
<double> = 5.2;
386 double d0b
= n0b::pi0b
<double>;
390 T pi1a
= T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
392 // expected-note@-2 {{explicit instantiation refers here}}
396 T pi1b
= T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
398 // expected-note@-2 {{explicit instantiation refers here}}
406 template float pi1a
<float>;
408 // expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
410 float f1
= pi1a
<float>;
412 template<> double pi1a
<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
413 double d1
= pi1a
<double>;
417 int i1
= n1::pi1b
<int>;
419 template float n1::pi1b
<float>;
421 // expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
423 float f1
= n1::pi1b
<float>;
425 template<> double n1::pi1b
<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
426 double d1
= n1::pi1b
<double>;
430 namespace nested_name
{
431 template<typename T
> int a
; // expected-note {{variable template 'a' declared here}}
432 a
<int>::b c
; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
434 class a
<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
435 enum a
<int> {}; // expected-error {{expected identifier or '{'}}
439 template<typename T
> int a
;
440 int a
<int>; // expected-error {{requires 'template<>'}}
445 template<typename T
> const auto x
= 1;
446 static_assert(x
<int> == 1, "");
451 template <typename T
> int* f();
452 template <typename T
> void f();
453 template<> int f
<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
455 template <typename T
> void g();
456 template<> int g
<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}
460 template <typename
... Args
> struct Variadic_t
{ };
461 template <typename
... Args
> Variadic_t
<Args
...> Variadic
;
462 auto variadic1
= Variadic
<>;
463 auto variadic2
= Variadic
<int, int>;
466 namespace VexingParse
{
467 template <typename
> int var
; // expected-note {{declared here}}
468 int x(var
); // expected-error {{use of variable template 'var' requires template arguments}}