diff options
Diffstat (limited to 'test/SemaTemplate/temp_arg_nontype.cpp')
-rw-r--r-- | test/SemaTemplate/temp_arg_nontype.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp new file mode 100644 index 0000000..fe18fe6 --- /dev/null +++ b/test/SemaTemplate/temp_arg_nontype.cpp @@ -0,0 +1,124 @@ +// RUN: clang-cc -fsyntax-only -std=c++98 -verify %s +template<int N> struct A; // expected-note 5{{template parameter is declared here}} + +A<0> *a0; + +A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int (void)'}} + +A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}} + +A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}} + +// C++ [temp.arg.nontype]p5: +A<A> *a4; // expected-error{{must have an integral or enumeration type}} \ + // FIXME: the error message above is a bit lame + +enum E { Enumerator = 17 }; +A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}} +template<E Value> struct A1; // expected-note{{template parameter is declared here}} +A1<Enumerator> *a6; // okay +A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'enum E'}} + +const long LongValue = 12345678; +A<LongValue> *a8; +const short ShortValue = 17; +A<ShortValue> *a9; + +int f(int); +A<f(17)> *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}} + +class X { +public: + X(); + X(int, int); + operator int() const; +}; +A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'class X' must have an integral or enumeration type}} + +template<X const *Ptr> struct A2; + +X *X_ptr; +X an_X; +X array_of_Xs[10]; +A2<X_ptr> *a12; +A2<array_of_Xs> *a13; +A2<&an_X> *a13_2; +A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} + +float f(float); + +float g(float); +double g(double); + +int h(int); +float h2(float); + +template<int fp(int)> struct A3; // expected-note 2{{template parameter is declared here}} +A3<h> *a14_1; +A3<&h> *a14_2; +A3<f> *a14_3; +A3<&f> *a14_4; +A3<h2> *a14_6; // expected-error{{non-type template argument of type 'float (*)(float)' cannot be converted to a value of type 'int (*)(int)'}} +A3<g> *a14_7; // expected-error{{non-type template argument of type '<overloaded function type>' cannot be converted to a value of type 'int (*)(int)'}} +// FIXME: the first error includes the string <overloaded function +// type>, which makes Doug slightly unhappy. + + +struct Y { } y; + +volatile X * X_volatile_ptr; +template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}} +A4<an_X> *a15_1; // okay +A4<*X_volatile_ptr> *a15_2; // expected-error{{reference binding of non-type template parameter of type 'class X const &' to template argument of type 'class X volatile' ignores qualifiers}} +A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'class X const &' cannot bind to template argument of type 'struct Y'}} \ + // FIXME: expected-error{{expected unqualified-id}} + +template<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}} +A5<h> *a16_1; +A5<f> *a16_3; +A5<h2> *a16_6; // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (&)(int)'}} +A5<g> *a14_7; // expected-error{{non-type template argument of type '<overloaded function type>' cannot be converted to a value of type 'int (&)(int)'}} +// FIXME: the first error includes the string <overloaded function +// type>, which makes Doug slightly unhappy. + +struct Z { + int foo(int); + float bar(float); + int bar(int); + double baz(double); + + int int_member; + float float_member; +}; +template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}} +A6<&Z::foo> *a17_1; +A6<&Z::bar> *a17_2; +A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (struct Z::*)(double)' cannot be converted to a value of type 'int (struct Z::*)(int)'}} + + +template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}} +template<int Z::*pm> struct A7c; +A7<&Z::int_member> *a18_1; +A7c<&Z::int_member> *a18_2; +A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float struct Z::*' cannot be converted to a value of type 'int struct Z::*'}} +A7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} + +template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}} + +Overflow<5> *overflow1; // okay +Overflow<256> *overflow2; // expected-error{{non-type template argument value '256' is too large for template parameter of type 'unsigned char'}} + + +template<unsigned> struct Signedness; // expected-note{{template parameter is declared here}} +Signedness<10> *signedness1; // okay +Signedness<-10> *signedness2; // expected-error{{non-type template argument provides negative value '-10' for unsigned template parameter of type 'unsigned int'}} + +// Check canonicalization of template arguments. +template<int (*)(int, int)> struct FuncPtr0; +int func0(int, int); +extern FuncPtr0<&func0> *fp0; +template<int (*)(int, int)> struct FuncPtr0; +extern FuncPtr0<&func0> *fp0; +int func0(int, int); +extern FuncPtr0<&func0> *fp0; + |