2013-08-22 08:59:14 +08:00
// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
2013-08-06 09:03:05 +08:00
2013-08-22 08:59:14 +08:00
# ifdef PRECXX11
2013-08-06 09:03:05 +08:00
# define CONST const
2013-08-22 08:59:14 +08:00
# else
# define CONST constexpr
2013-08-06 09:03:05 +08:00
# endif
template < typename T >
T pi = T ( 3.1415926535897932385 ) ; // expected-note {{template is declared here}}
template < typename T >
CONST T cpi = T ( 3.1415926535897932385 ) ; // expected-note {{template is declared here}}
2013-08-13 10:02:26 +08:00
template < typename T > extern CONST T vc ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-13 10:02:26 +08:00
// expected-error@-2 {{constexpr variable declaration must be a definition}}
# endif
2013-08-06 09:03:05 +08:00
namespace use_in_top_level_funcs {
void good ( ) {
int ipi = pi < int > ;
int icpi = cpi < int > ;
double dpi = pi < double > ;
double dcpi = cpi < double > ;
}
void no_deduce ( ) {
// template arguments are not deduced for uses of variable templates.
int ipi = pi ; // expected-error {{cannot refer to variable template 'pi' without a template argument list}}
int icpi = cpi ; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}}
}
template < typename T >
T circular_area ( T r ) {
return pi < T > * r * r ;
}
template < typename T >
CONST T const_circular_area ( T r ) {
return cpi < T > * r * r ;
}
double use_circular_area ( double r ) {
CONST float t = const_circular_area ( 2.0 ) - 12 ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
static_assert ( const_circular_area ( 2 ) = = 12 , " " ) ;
CONST int test = ( t > 0 ) & & ( t < 1 ) ;
static_assert ( test , " " ) ;
# endif
return circular_area ( r ) ;
}
}
namespace shadow {
void foo ( ) {
int ipi0 = pi < int > ;
int pi ;
int a = pi ;
int ipi = pi < int > ; / / expected - error { { expected ' ( ' for function - style cast or type construction } } \
// expected-error {{expected expression}}
}
}
namespace odr_tmpl {
namespace pv_cvt {
int v ; // expected-note {{previous definition is here}}
template < typename T > T v ; // expected-error {{redefinition of 'v' as different kind of symbol}}
}
namespace pvt_cv {
template < typename T > T v ; // expected-note {{previous definition is here}}
2013-08-14 11:09:19 +08:00
int v ; // expected-error {{redefinition of 'v' as different kind of symbol}}
2013-08-06 09:03:05 +08:00
}
namespace pvt_cvt {
template < typename T > T v0 ; // expected-note {{previous definition is here}}
template < typename T > T v0 ; // expected-error {{redefinition of 'v0'}}
template < typename T > T v ; // expected-note {{previous definition is here}}
template < typename T > int v ; // expected-error {{redefinition of 'v'}}
2014-01-17 07:39:20 +08:00
template < typename T > extern int v1 ; // expected-note {{previous template declaration is here}}
2013-08-06 09:03:05 +08:00
template < int I > int v1 ; // expected-error {{template parameter has a different kind in template redeclaration}}
}
namespace pvt_use {
template < typename T > T v ;
v = 10 ; // expected-error {{C++ requires a type specifier for all declarations}}
}
namespace pvt_diff_params {
2014-01-17 07:39:20 +08:00
template < typename T , typename > T v ; // expected-note {{previous template declaration is here}}
template < typename T > T v ; // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
2013-08-06 09:03:05 +08:00
template < typename T , typename , typename > T v ; // expected-error {{too many template parameters in template redeclaration}}
}
namespace pvt_extern {
template < typename T > T v = T ( ) ;
template < typename T > extern T v ; / / redeclaration is allowed \
// expected-note {{previous definition is here}}
template < typename T > extern int v ; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
template < typename T > extern auto v ; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
# endif
2013-08-14 11:09:19 +08:00
template < typename T > T var = T ( ) ; // expected-note {{previous definition is here}}
extern int var ; // expected-error {{redefinition of 'var' as different kind of symbol}}
2013-08-06 09:03:05 +08:00
}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
namespace pvt_auto {
template < typename T > auto v0 ; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
template < typename T > auto v1 = T ( ) ; // expected-note {{previous definition is here}}
template < typename T > int v1 ; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
template < typename T > auto v2 = T ( ) ; // expected-note {{previous definition is here}}
template < typename T > T v2 ; // expected-error {{redefinition of 'v2'}}
template < typename T > auto v3 = T ( ) ; // expected-note {{previous definition is here}}
template < typename T > extern T v3 ; // expected-error {{redefinition of 'v3' with a different type: 'T' vs 'auto'}}
template < typename T > auto v4 = T ( ) ;
template < typename T > extern auto v4 ; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
}
# endif
2013-08-15 04:15:02 +08:00
}
2013-08-06 09:03:05 +08:00
namespace explicit_instantiation {
template < typename T >
T pi0a = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi0a' declared here}}
template float pi0a < int > ; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
template < typename T >
T pi0b = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi0b' declared here}}
template CONST int pi0b < int > ; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
template < typename T >
T pi0c = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi0c' declared here}}
template int pi0c < const int > ; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
template < typename T >
T pi0 = T ( 3.1415926535897932385 ) ;
template int pi0 < int > ; // expected-note {{previous explicit instantiation is here}}
template int pi0 < int > ; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
template < typename T >
CONST T pi1a = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi1a' declared here}}
template int pi1a < int > ; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
template < typename T >
CONST T pi1b = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi1b' declared here}}
template int pi1b < const int > ; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
template < typename T >
CONST T pi1 = T ( 3.1415926535897932385 ) ;
template CONST int pi1 < int > ; // expected-note {{previous explicit instantiation is here}}
template CONST int pi1 < int > ; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
namespace auto_var {
template < typename T > auto var0 = T ( ) ;
template auto var0 < int > ; // expected-error {{'auto' variable template instantiation is not allowed}}
template < typename T > auto var = T ( ) ;
template int var < int > ;
}
# endif
2013-09-18 10:10:12 +08:00
template < typename = int > int missing_args ; // expected-note {{here}}
template int missing_args ; // expected-error {{must specify a template argument list}}
2013-08-06 09:03:05 +08:00
namespace extern_var {
// TODO:
}
}
namespace explicit_specialization {
namespace good {
template < typename T1 , typename T2 >
CONST int pi2 = 1 ;
template < typename T >
CONST int pi2 < T , int > = 2 ;
template < typename T >
CONST int pi2 < int , T > = 3 ;
template < > CONST int pi2 < int , int > = 4 ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
void foo ( ) {
static_assert ( pi2 < int , int > = = 4 , " " ) ;
static_assert ( pi2 < float , int > = = 2 , " " ) ;
static_assert ( pi2 < int , float > = = 3 , " " ) ;
static_assert ( pi2 < int , float > = = pi2 < int , double > , " " ) ;
static_assert ( pi2 < float , float > = = 1 , " " ) ;
static_assert ( pi2 < float , float > = = pi2 < float , double > , " " ) ;
}
# endif
}
namespace ambiguous {
template < typename T1 , typename T2 >
CONST int pi2 = 1 ;
template < typename T >
CONST int pi2 < T , int > = 2 ; // expected-note {{partial specialization matches [with T = int]}}
template < typename T >
CONST int pi2 < int , T > = 3 ; // expected-note {{partial specialization matches [with T = int]}}
void foo ( ) {
int a = pi2 < int , int > ; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
}
}
namespace type_changes {
template < typename T >
T pi0 = T ( 3.1415926535897932385 ) ;
template < > float pi0 < int > = 10 ;
template < > int pi0 < const int > = 10 ;
template < typename T >
T pi1 = T ( 3.1415926535897932385 ) ;
template < > CONST int pi1 < int > = 10 ;
template < typename T >
T pi2 = T ( 3.1415926535897932385 ) ;
template < > int pi2 < const int > = 10 ;
template < typename T >
CONST T pi4 = T ( 3.1415926535897932385 ) ;
template < > int pi4 < int > = 10 ;
}
namespace redefinition {
template < typename T >
T pi0 = T ( 3.1415926535897932385 ) ;
template < > int pi0 < int > = 10 ; // expected-note 3{{previous definition is here}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
// expected-note@-2 {{previous definition is here}}
# endif
template < > int pi0 < int > = 10 ; // expected-error {{redefinition of 'pi0<int>'}}
template < > CONST int pi0 < int > = 10 ; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
template < > float pi0 < int > = 10 ; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
template < > auto pi0 < int > = 10 ; // expected-error {{redefinition of 'pi0<int>'}}
# endif
template < typename T >
CONST T pi1 = T ( 3.1415926535897932385 ) ;
template < > CONST int pi1 < int > = 10 ; // expected-note {{previous definition is here}}
template < > CONST int pi1 < int > = 10 ; // expected-error {{redefinition of 'pi1<int>'}}
}
namespace before_instantiation {
template < typename T >
T pi0 = T ( 3.1415926535897932385 ) ; // expected-note {{variable template 'pi0' declared here}}
template < > int pi0 < int > = 10 ;
template int pi0 < int > ;
template float pi0 < int > ; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
template < typename T1 , typename T2 >
CONST int pi2 = 1 ;
template < typename T > CONST int pi2 < T , int > = 2 ;
template CONST int pi2 < int , int > ;
}
namespace after_instantiation {
template < typename T >
T pi0 = T ( 3.1415926535897932385 ) ;
template int pi0 < int > ; // expected-note 2{{explicit instantiation first required here}}
template < > int pi0 < int > = 10 ; // expected-error {{explicit specialization of 'pi0' after instantiation}}
template < > float pi0 < int > ; // expected-error {{explicit specialization of 'pi0' after instantiation}}
template < typename T1 , typename T2 >
CONST int pi2 = 1 ;
template CONST int pi2 < int , int > ;
template < typename T > CONST int pi2 < T , int > = 2 ;
}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
namespace auto_var {
template < typename T , typename > auto var0 = T ( ) ;
template < typename T > auto var0 < T , int > = T ( ) ;
template < > auto var0 < int , int > = 7 ;
template < typename T , typename > auto var = T ( ) ;
template < typename T > T var < T , int > = T ( 5 ) ;
template < > int var < int , int > = 7 ;
void foo ( ) {
int i0 = var0 < int , int > ;
int b = var < int , int > ;
}
}
# endif
namespace extern_var {
// TODO:
}
namespace diff_type {
// TODO:
2013-09-24 12:49:23 +08:00
template < typename T > T * var = new T ( ) ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
template < typename T > auto var < T * > = T ( ) ; // expected-note {{previous definition is here}}
template < typename T > T var < T * > = T ( ) ; // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
# endif
}
}
2013-08-15 04:15:02 +08:00
namespace narrowing {
template < typename T > T v = { 1234 } ; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-15 04:15:02 +08:00
/ / expected - error @ - 2 { { constant expression evaluates to 1234 which cannot be narrowed to type ' char ' } } \
// expected-note@-2 {{override this message by inserting an explicit cast}}
# endif
int k = v < char > ; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
}
2013-08-06 09:03:05 +08:00
namespace use_in_structs {
// TODO:
}
namespace attributes {
// TODO:
}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
namespace arrays {
template < typename T >
T * arr = new T [ 10 ] { T ( 10 ) , T ( 23 ) } ;
float f = 10.5 ;
template < > float * arr < float > = & f ;
void bar ( ) {
int * iarr = arr < int > ;
iarr [ 0 ] = 1 ;
iarr [ 2 ] = 3 ;
iarr [ 6 ] = - 2 ;
float ff = * arr < float > ;
float nof = arr < float > [ 3 ] ; // No bounds-check in C++
}
}
# endif
namespace nested {
namespace n0a {
template < typename T >
T pi0a = T ( 3.1415926535897932385 ) ;
}
using namespace n0a ;
int i0a = pi0a < int > ;
template float pi0a < float > ;
float f0a = pi0a < float > ;
template < > double pi0a < double > = 5.2 ;
double d0a = pi0a < double > ;
namespace n0b {
template < typename T >
T pi0b = T ( 3.1415926535897932385 ) ;
}
int i0b = n0b : : pi0b < int > ;
template float n0b : : pi0b < float > ;
float f0b = n0b : : pi0b < float > ;
template < > double n0b : : pi0b < double > = 5.2 ;
double d0b = n0b : : pi0b < double > ;
namespace n1 {
template < typename T >
2014-01-17 07:39:20 +08:00
T pi1a = T ( 3.1415926535897932385 ) ; // expected-note {{explicitly specialized declaration is here}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
// expected-note@-2 {{explicit instantiation refers here}}
# endif
template < typename T >
T pi1b = T ( 3.1415926535897932385 ) ; // expected-note {{explicitly specialized declaration is here}}
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
// expected-note@-2 {{explicit instantiation refers here}}
# endif
}
namespace use_n1a {
using namespace n1 ;
int i1 = pi1a < int > ;
template float pi1a < float > ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
# endif
float f1 = pi1a < float > ;
2014-01-17 07:39:20 +08:00
template < > double pi1a < double > = 5.2 ; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
2013-08-06 09:03:05 +08:00
double d1 = pi1a < double > ;
}
namespace use_n1b {
int i1 = n1 : : pi1b < int > ;
template float n1 : : pi1b < float > ;
2013-08-22 08:59:14 +08:00
# ifndef PRECXX11
2013-08-06 09:03:05 +08:00
// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
# endif
float f1 = n1 : : pi1b < float > ;
template < > double n1 : : pi1b < double > = 5.2 ; / / expected - error { { cannot define or redeclare ' pi1b ' here because namespace ' use_n1b ' does not enclose namespace ' n1 ' } } \
// expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
double d1 = n1 : : pi1b < double > ;
}
}
2013-12-04 08:28:23 +08:00
namespace nested_name {
2013-12-04 08:47:45 +08:00
template < typename T > int a ; // expected-note {{variable template 'a' declared here}}
a < int > : : b c ; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
2013-12-04 08:28:23 +08:00
class a < int > { } ; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
enum a < int > { } ; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
}