1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s 4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s 5 // RUN: %clang_cc1 -fsyntax-only -verify %s 6 7 // C++0x [temp.arg.nontype] p5: 8 // The following conversions are performed on each expression used as 9 // a non-type template-argument. If a non-type template-argument cannot be 10 // converted to the type of the corresponding template-parameter then the 11 // program is ill-formed. 12 // -- for a non-type template-parameter of integral or enumeration type, 13 // integral promotions (4.5) and integral conversions (4.7) are applied. 14 namespace integral_parameters { 15 template<short s> struct X0 { }; 16 X0<17> x0i; 17 X0<'a'> x0c; 18 template<char c> struct X1 { }; 19 X1<100l> x1l; 20 } 21 22 // -- for a non-type template-parameter of type pointer to object, 23 // qualification conversions (4.4) and the array-to-pointer conversion 24 // (4.2) are applied; if the template-argument is of type 25 // std::nullptr_t, the null pointer conversion (4.10) is applied. 26 namespace pointer_to_object_parameters { 27 // PR6226 28 struct Str { 29 Str(const char *); 30 }; 31 32 template<const char *s> 33 struct A { getpointer_to_object_parameters::A34 Str get() { return s; } 35 }; 36 37 char hello[6] = "Hello"; 38 extern const char world[6]; 39 const char world[6] = "world"; test()40 void test() { 41 (void)A<hello>().get(); 42 (void)A<world>().get(); 43 } 44 45 class X { 46 public: 47 X(); 48 X(int, int); 49 operator int() const; 50 }; 51 52 template<X const *Ptr> struct A2; // expected-note 0-1{{template parameter is declared here}} 53 54 X *X_ptr; // expected-note 0-1{{declared here}} 55 X an_X; 56 X array_of_Xs[10]; 57 A2<X_ptr> *a12; 58 #if __cplusplus < 201103L 59 // expected-error@-2 {{must have its address taken}} 60 #else 61 // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}} 62 #endif 63 A2<array_of_Xs> *a13; 64 A2<&an_X> *a13_2; 65 A2<(&an_X)> *a13_3; 66 #if __cplusplus < 201103L 67 // expected-warning@-2 {{address non-type template argument cannot be surrounded by parentheses}} 68 #endif 69 70 // PR6244 71 struct X1 {} X1v; 72 template <X1*> struct X2 { }; 73 template <X1* Value> struct X3 : X2<Value> { }; 74 struct X4 : X3<&X1v> { }; 75 76 // PR6563 77 int *bar; // expected-note 0-1{{declared here}} 78 template <int *> struct zed {}; // expected-note 0-2{{template parameter is declared here}} 79 void g(zed<bar>*); 80 #if __cplusplus < 201103L 81 // expected-error@-2 {{must have its address taken}} 82 #else 83 // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}} 84 #endif 85 86 int baz; // expected-note 0-1{{declared here}} 87 void g2(zed<baz>*); 88 #if __cplusplus < 201103L 89 // expected-error@-2 {{must have its address taken}} 90 #elif __cplusplus <= 201402L 91 // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-const variable}} 92 #else 93 // expected-error@-6 {{not implicitly convertible to 'int *'}} 94 #endif 95 96 void g3(zed<&baz>*); // okay 97 } 98 99 // -- For a non-type template-parameter of type reference to object, no 100 // conversions apply. The type referred to by the reference may be more 101 // cv-qualified than the (otherwise identical) type of the 102 // template-argument. The template-parameter is bound directly to the 103 // template-argument, which shall be an lvalue. 104 namespace reference_parameters { 105 template <int& N> struct S0 { }; // expected-note 0-3{{template parameter is declared here}} 106 template <const int& N> struct S1 { }; // expected-note 0-2{{template parameter is declared here}} 107 template <volatile int& N> struct S2 { }; // expected-note 0-2{{template parameter is declared here}} 108 template <const volatile int& N> struct S3 { }; 109 int i; 110 extern const int ci; 111 volatile int vi; 112 extern const volatile int cvi; test()113 void test() { 114 S0<i> s0; 115 S0<ci> s0c; // expected-error{{type 'const int'}} 116 S0<vi> s0v; // expected-error{{type 'volatile int'}} 117 S0<cvi> s0cv; // expected-error{{type 'const volatile int'}} 118 119 S1<i> s1; 120 S1<ci> s1c; 121 S1<vi> s1v; // expected-error{{type 'volatile int'}} 122 S1<cvi> s1cv; // expected-error{{type 'const volatile int'}} 123 124 S2<i> s2; 125 S2<ci> s2c; // expected-error{{type 'const int'}} 126 S2<vi> s2v; 127 S2<cvi> s2cv; // expected-error{{type 'const volatile int'}} 128 129 S3<i> s3; 130 S3<ci> s3c; 131 S3<vi> s3v; 132 S3<cvi> s3cv; 133 } 134 135 namespace PR6250 { inc()136 template <typename T, const T &ref> void inc() { 137 ref++; // expected-error{{read-only variable is not assignable}} 138 } 139 bind()140 template<typename T, const T &ref> void bind() { 141 T &ref2 = ref; // expected-error{{drops 'const' qualifier}} 142 } 143 144 int counter; test()145 void test() { 146 inc<int, counter>(); // expected-note{{instantiation of}} 147 bind<int, counter>(); // expected-note{{instantiation of}} 148 } 149 } 150 151 namespace PR6749 { 152 template <int& i> struct foo {}; // expected-note 0-1{{template parameter is declared here}} 153 int x, &y = x; 154 foo<y> f; 155 #if __cplusplus <= 201402L 156 // expected-error@-2 {{is not an object}} 157 #endif 158 } 159 } 160 161 // -- For a non-type template-parameter of type pointer to function, the 162 // function-to-pointer conversion (4.3) is applied; if the 163 // template-argument is of type std::nullptr_t, the null pointer 164 // conversion (4.10) is applied. If the template-argument represents 165 // a set of overloaded functions (or a pointer to such), the matching 166 // function is selected from the set (13.4). 167 namespace pointer_to_function { 168 template<int (*)(int)> struct X0 { }; // expected-note 0-3{{template parameter is declared here}} 169 int f(int); 170 int f(float); 171 int g(float); 172 int (*funcptr)(int); // expected-note 0-1{{declared here}} 173 void x0a(X0<f>); 174 void x0b(X0<&f>); 175 void x0c(X0<g>); // expected-error-re{{type 'int (float)' {{.*}}convert{{.*}} 'int (*)(int)'}} 176 void x0d(X0<&g>); // expected-error-re{{type 'int (*)(float)' {{.*}}convert{{.*}} 'int (*)(int)'}} 177 void x0e(X0<funcptr>); 178 #if __cplusplus < 201103L 179 // expected-error@-2 {{must have its address taken}} 180 #else 181 // expected-error@-4 {{not a constant expression}} expected-note@-4 {{read of non-constexpr variable}} 182 #endif 183 } 184 185 // -- For a non-type template-parameter of type reference to function, no 186 // conversions apply. If the template-argument represents a set of 187 // overloaded functions, the matching function is selected from the set 188 // (13.4). 189 namespace reference_to_function { 190 template<int (&)(int)> struct X0 { }; // expected-note 0-4{{template parameter is declared here}} 191 int f(int); 192 int f(float); 193 int g(float); 194 int (*funcptr)(int); 195 void x0a(X0<f>); 196 #if __cplusplus <= 201402L 197 void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} 198 void x0c(X0<g>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}} 199 void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}} 200 void x0e(X0<funcptr>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}} 201 #else 202 void x0b(X0<&f>); // expected-error{{value of type '<overloaded function type>' is not implicitly convertible to 'int (&)(int)'}} 203 void x0c(X0<g>); // expected-error{{value of type 'int (float)' is not implicitly convertible to 'int (&)(int)'}} 204 void x0d(X0<&g>); // expected-error{{value of type 'int (*)(float)' is not implicitly convertible to 'int (&)(int)'}} 205 void x0e(X0<funcptr>); // expected-error{{value of type 'int (*)(int)' is not implicitly convertible to 'int (&)(int)'}} 206 #endif 207 } 208 // -- For a non-type template-parameter of type pointer to member function, 209 // if the template-argument is of type std::nullptr_t, the null member 210 // pointer conversion (4.11) is applied; otherwise, no conversions 211 // apply. If the template-argument represents a set of overloaded member 212 // functions, the matching member function is selected from the set 213 // (13.4). 214 namespace pointer_to_member_function { 215 struct X { }; 216 struct Y : X { 217 int f(int); 218 int g(int); 219 int g(float); 220 float h(float); 221 }; 222 223 template<int (Y::*)(int)> struct X0 {}; // expected-note 0-1{{template parameter is declared here}} 224 X0<&Y::f> x0a; 225 X0<&Y::g> x0b; 226 X0<&Y::h> x0c; // expected-error-re{{type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}} 227 } 228 229 // -- For a non-type template-parameter of type pointer to data member, 230 // qualification conversions (4.4) are applied; if the template-argument 231 // is of type std::nullptr_t, the null member pointer conversion (4.11) 232 // is applied. 233 namespace pointer_to_member_data { 234 struct X { int x; }; 235 struct Y : X { int y; }; 236 237 template<int Y::*> struct X0 {}; // expected-note 0-1{{template parameter is declared here}} 238 X0<&Y::y> x0a; 239 X0<&Y::x> x0b; 240 #if __cplusplus <= 201402L 241 // expected-error@-2 {{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} 242 #else 243 // expected-error@-4 {{conversion from 'int pointer_to_member_data::X::*' to 'int pointer_to_member_data::Y::*' is not allowed in a converted constant expression}} 244 #endif 245 246 // Test qualification conversions 247 template<const int Y::*> struct X1 {}; 248 X1<&Y::y> x1a; 249 } 250