p5.cpp revision 0f4a577f4522b4707006250ba832301c375807cb
1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3// C++0x [temp.arg.nontype] p5: 4// The following conversions are performed on each expression used as 5// a non-type template-argument. If a non-type template-argument cannot be 6// converted to the type of the corresponding template-parameter then the 7// program is ill-formed. 8// -- for a non-type template-parameter of integral or enumeration type, 9// integral promotions (4.5) and integral conversions (4.7) are applied. 10// -- for a non-type template-parameter of type pointer to object, 11// qualification conversions (4.4) and the array-to-pointer conversion 12// (4.2) are applied; if the template-argument is of type 13// std::nullptr_t, the null pointer conversion (4.10) is applied. 14namespace pointer_to_object_parameters { 15 // PR6226 16 struct Str { 17 Str(const char *); 18 }; 19 20 template<const char *s> 21 struct A { 22 Str get() { return s; } 23 }; 24 25 char hello[6] = "Hello"; 26 extern const char world[6]; 27 const char world[6] = "world"; 28 void test() { 29 (void)A<hello>().get(); 30 (void)A<world>().get(); 31 } 32 33 class X { 34 public: 35 X(); 36 X(int, int); 37 operator int() const; 38 }; 39 40 template<X const *Ptr> struct A2; 41 42 X *X_ptr; 43 X an_X; 44 X array_of_Xs[10]; 45 A2<X_ptr> *a12; 46 A2<array_of_Xs> *a13; 47 A2<&an_X> *a13_2; 48 A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} 49 50 // PR6244 51 struct X1 {} X1v; 52 template <X1*> struct X2 { }; 53 template <X1* Value> struct X3 : X2<Value> { }; 54 struct X4 : X3<&X1v> { }; 55} 56 57// -- For a non-type template-parameter of type reference to object, no 58// conversions apply. The type referred to by the reference may be more 59// cv-qualified than the (otherwise identical) type of the 60// template-argument. The template-parameter is bound directly to the 61// template-argument, which shall be an lvalue. 62namespace reference_parameters { 63 template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}} 64 template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}} 65 template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}} 66 template <const volatile int& N> struct S3 { }; 67 int i; 68 extern const int ci; 69 volatile int vi; 70 extern const volatile int cvi; 71 void test() { 72 S0<i> s0; 73 S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}} 74 S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}} 75 S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}} 76 77 S1<i> s1; 78 S1<ci> s1c; 79 S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}} 80 S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}} 81 82 S2<i> s2; 83 S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}} 84 S2<vi> s2v; 85 S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}} 86 87 S3<i> s3; 88 S3<ci> s3c; 89 S3<vi> s3v; 90 S3<cvi> s3cv; 91 } 92 93 namespace PR6250 { 94 template <typename T, const T &ref> void inc() { 95 ref++; // expected-error{{read-only variable is not assignable}} 96 } 97 98 template<typename T, const T &ref> void bind() { 99 T &ref2 = ref; // expected-error{{drops qualifiers}} 100 } 101 102 int counter; 103 void test() { 104 inc<int, counter>(); // expected-note{{instantiation of}} 105 bind<int, counter>(); // expected-note{{instantiation of}} 106 } 107 } 108} 109 110// -- For a non-type template-parameter of type pointer to function, the 111// function-to-pointer conversion (4.3) is applied; if the 112// template-argument is of type std::nullptr_t, the null pointer 113// conversion (4.10) is applied. If the template-argument represents 114// a set of overloaded functions (or a pointer to such), the matching 115// function is selected from the set (13.4). 116// -- For a non-type template-parameter of type reference to function, no 117// conversions apply. If the template-argument represents a set of 118// overloaded functions, the matching function is selected from the set 119// (13.4). 120// -- For a non-type template-parameter of type pointer to member function, 121// if the template-argument is of type std::nullptr_t, the null member 122// pointer conversion (4.11) is applied; otherwise, no conversions 123// apply. If the template-argument represents a set of overloaded member 124// functions, the matching member function is selected from the set 125// (13.4). 126// -- For a non-type template-parameter of type pointer to data member, 127// qualification conversions (4.4) are applied; if the template-argument 128// is of type std::nullptr_t, the null member pointer conversion (4.11) 129// is applied. 130