1 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 2 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s 3 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1y -verify -fsyntax-only %s -DCPP1Y 4 5 #define CONST const 6 7 #ifdef PRECXX11 8 #define static_assert _Static_assert 9 #endif 10 11 class A { 12 template<typename T> CONST T wrong; // expected-error {{non-static data member 'wrong' cannot be declared as a template}} 13 template<typename T> CONST T wrong_init = 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}} 14 template<typename T, typename T0> static CONST T right = T(100); 15 template<typename T> static CONST T right<T,int> = 5; 16 template<typename T> CONST int right<int,T>; // expected-error {{non-static data member 'right' cannot be declared as a template}} 17 template<typename T> CONST float right<float,T> = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}} 18 #ifdef PRECXX11 19 // expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}} 20 #else 21 // expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}} 22 // expected-note@-5 {{add 'constexpr'}} 23 #endif 24 template<> CONST int right<int,int> = 7; 25 template<> CONST float right<float,int>; 26 template static CONST int right<int,int>; // expected-error {{expected '<' after 'template'}} 27 }; 28 29 namespace out_of_line { 30 class B0 { 31 template<typename T, typename T0> static CONST T right = T(100); 32 template<typename T> static CONST T right<T,int> = T(5); 33 }; 34 template<> CONST int B0::right<int,int> = 7; // expected-note {{previous}} 35 template CONST int B0::right<int,int>; // expected-warning {{has no effect}} 36 template<> CONST int B0::right<int,float>; // expected-note {{previous}} 37 template CONST int B0::right<int,float>; // expected-warning {{has no effect}} 38 39 class B1 { 40 template<typename T, typename T0> static CONST T right; 41 template<typename T> static CONST T right<T,int>; 42 }; 43 template<typename T, typename T0> CONST T B1::right = T(100); 44 template<typename T> CONST T B1::right<T,int> = T(5); 45 46 class B2 { 47 template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}} 48 template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}} 49 }; 50 template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}} 51 template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}} 52 53 class B3 { 54 template<typename T, typename T0> static CONST T right = T(100); 55 template<typename T> static CONST T right<T,int> = T(5); 56 }; 57 template<typename T, typename T0> CONST T B3::right; 58 template<typename T> CONST T B3::right<T,int>; 59 60 class B4 { 61 template<typename T, typename T0> static CONST T a; 62 template<typename T> static CONST T a<T,int> = T(100); 63 template<typename T, typename T0> static CONST T b = T(100); 64 template<typename T> static CONST T b<T,int>; 65 }; 66 template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} 67 template<typename T> CONST T B4::a<T,int>; 68 template CONST int B4::a<int,char>; // expected-note {{in instantiation of}} 69 template CONST int B4::a<int,int>; 70 71 template<typename T, typename T0> CONST T B4::b; 72 template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} 73 template CONST int B4::b<int,char>; 74 template CONST int B4::b<int,int>; // expected-note {{in instantiation of}} 75 } 76 77 namespace non_const_init { 78 class A { 79 template<typename T> static T wrong_inst_undefined = T(10); // expected-note {{refers here}} 80 template<typename T> static T wrong_inst_defined = T(10); // expected-error {{non-const static data member must be initialized out of line}} 81 template<typename T> static T wrong_inst_out_of_line; 82 }; 83 84 template const int A::wrong_inst_undefined<const int>; // expected-error {{undefined}} 85 86 template<typename T> T A::wrong_inst_defined; 87 template const int A::wrong_inst_defined<const int>; 88 template int A::wrong_inst_defined<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst_defined<int>' requested here}} 89 90 template<typename T> T A::wrong_inst_out_of_line = T(10); 91 template int A::wrong_inst_out_of_line<int>; 92 93 class B { 94 template<typename T> static T wrong_inst; // expected-note {{refers here}} 95 template<typename T> static T wrong_inst<T*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} expected-note {{refers here}} 96 97 template<typename T> static T wrong_inst_fixed; 98 template<typename T> static T wrong_inst_fixed<T*>; 99 }; 100 template int B::wrong_inst<int>; // expected-error {{undefined}} 101 // FIXME: It'd be better to produce the 'explicit instantiation of undefined 102 // template' diagnostic here, not the 'must be initialized out of line' 103 // diagnostic. 104 template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}} 105 template const int B::wrong_inst<const int*>; // expected-error {{undefined}} 106 template<typename T> T B::wrong_inst_fixed = T(100); 107 template int B::wrong_inst_fixed<int>; 108 109 class C { 110 template<typename T> static CONST T right_inst = T(10); // expected-note {{here}} 111 template<typename T> static CONST T right_inst<T*> = T(100); // expected-note {{here}} 112 }; 113 template CONST int C::right_inst<int>; // expected-error {{undefined variable template}} 114 template CONST int C::right_inst<int*>; // expected-error {{undefined variable template}} 115 116 namespace pointers { 117 118 struct C0 { 119 template<typename U> static U Data; 120 template<typename U> static CONST U Data<U*> = U(); // expected-note {{here}} 121 122 template<typename U> static U Data2; 123 template<typename U> static CONST U Data2<U*> = U(); 124 }; 125 const int c0_test = C0::Data<int*>; 126 static_assert(c0_test == 0, ""); 127 template const int C0::Data<int*>; // expected-error {{undefined}} 128 129 template<typename U> const U C0::Data2<U*>; 130 template const int C0::Data2<int*>; 131 132 struct C1a { 133 template<typename U> static U Data; 134 template<typename U> static U* Data<U*>; // Okay, with out-of-line definition 135 }; 136 template<typename T> T* C1a::Data<T*> = new T(); 137 template int* C1a::Data<int*>; 138 139 struct C1b { 140 template<typename U> static U Data; 141 template<typename U> static CONST U* Data<U*>; // Okay, with out-of-line definition 142 }; 143 template<typename T> CONST T* C1b::Data<T*> = (T*)(0); 144 template CONST int* C1b::Data<int*>; 145 146 struct C2a { 147 template<typename U> static int Data; 148 template<typename U> static U* Data<U*> = new U(); // expected-error {{non-const static data member must be initialized out of line}} 149 }; 150 template int* C2a::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}} 151 152 struct C2b { 153 template<typename U> static int Data; 154 template<typename U> static U *const Data<U*> = (U*)(0); // expected-error {{static data member of type 'int *const'}} 155 }; 156 template<typename U> U *const C2b::Data<U*>; 157 template int *const C2b::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}} 158 } 159 } 160 161 #ifndef PRECXX11 162 namespace constexpred { 163 class A { 164 template<typename T> constexpr T wrong; // expected-error {{non-static data member 'wrong' cannot be declared as a template}} 165 // expected-error@-1 {{declaration of constexpr static data member 'wrong' requires an initializer}} 166 template<typename T> constexpr T wrong_init = 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}} 167 template<typename T, typename T0> static constexpr T right = T(100); 168 template<typename T> static constexpr T right<T,int> = 5; 169 template<typename T> constexpr int right<int,T>; // expected-error {{non-static data member 'right' cannot be declared as a template}} 170 // expected-error@-1 {{declaration of constexpr static data member 'right<int, T>' requires an initializer}} 171 template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}} 172 template<> constexpr int right<int,int> = 7; 173 template<> constexpr float right<float, int>; // expected-error {{declaration of constexpr static data member 'right<float, int>' requires an initializer}} 174 template static constexpr int right<int,int>; // expected-error {{expected '<' after 'template'}} 175 }; 176 } 177 #endif 178 179 namespace in_class_template { 180 181 template<typename T> 182 class D0 { 183 template<typename U> static U Data; // expected-note {{here}} 184 template<typename U> static CONST U Data<U*> = U(); 185 }; 186 template CONST int D0<float>::Data<int*>; 187 template int D0<float>::Data<int>; // expected-error {{undefined}} 188 template<typename T> template<typename U> const U D0<T>::Data<U*>; 189 190 template<typename T> 191 class D1 { 192 template<typename U> static U Data; 193 template<typename U> static U* Data<U*>; 194 }; 195 template<typename T> 196 template<typename U> U* D1<T>::Data<U*> = (U*)(0); 197 template int* D1<float>::Data<int*>; // expected-note {{previous}} 198 template int* D1<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 199 200 template<typename T> 201 class D2 { 202 template<typename U> static U Data; 203 template<typename U> static U* Data<U*>; 204 }; 205 template<> 206 template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1; 207 template int* D2<float>::Data<int*>; // expected-note {{previous}} 208 template int* D2<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 209 210 template<typename T> 211 struct D3 { 212 template<typename U> static CONST U Data = U(100); // expected-note {{here}} 213 }; 214 static_assert(D3<float>::Data<int> == 100, ""); 215 template const char D3<float>::Data<char>; // expected-error {{undefined}} 216 217 namespace bug_files { 218 template<typename T> 219 class D0a { 220 template<typename U> static U Data; 221 template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous declaration is here}} 222 }; 223 template<> 224 template<typename U> U D0a<float>::Data<U*> = U(100); // expected-error {{redefinition of 'Data'}} 225 226 // FIXME: We should accept this, and the corresponding case for class 227 // templates. 228 // 229 // [temp.class.spec.mfunc]/2: If the primary member template is explicitly 230 // specialized for a given specialization of the enclosing class template, 231 // the partial specializations of the member template are ignored 232 template<typename T> 233 class D1 { 234 template<typename U> static U Data; 235 template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous declaration is here}} 236 }; 237 template<> 238 template<typename U> U D1<float>::Data = U(10); 239 template<> 240 template<typename U> U D1<float>::Data<U*> = U(100); // expected-error{{redefinition of 'Data'}} 241 } 242 243 namespace definition_after_outer_instantiation { 244 template<typename A> struct S { 245 template<typename B> static const int V1; 246 template<typename B> static const int V2; // expected-note 3{{here}} 247 }; 248 template struct S<int>; 249 template<typename A> template<typename B> const int S<A>::V1 = 123; 250 template<typename A> template<typename B> const int S<A>::V2<B*> = 456; 251 252 static_assert(S<int>::V1<int> == 123, ""); 253 254 // FIXME: The first and third case below possibly should be accepted. We're 255 // not picking up partial specializations added after the primary template 256 // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2, 257 // and matches our behavior for member class templates, but it's not clear 258 // that this is intentional. See PR17294 and core-24030. 259 static_assert(S<int>::V2<int*> == 456, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2<int *>' is unknown}} 260 static_assert(S<int>::V2<int&> == 789, ""); // expected-error {{}} expected-note {{initializer of 'V2<int &>' is unknown}} 261 262 template<typename A> template<typename B> const int S<A>::V2<B&> = 789; 263 static_assert(S<int>::V2<int&> == 789, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2<int &>' is unknown}} 264 265 // All is OK if the partial specialization is declared before the implicit 266 // instantiation of the class template specialization. 267 static_assert(S<char>::V1<int> == 123, ""); 268 static_assert(S<char>::V2<int*> == 456, ""); 269 static_assert(S<char>::V2<int&> == 789, ""); 270 } 271 272 namespace incomplete_array { 273 template<typename T> extern T var[]; 274 template<typename T> T var[] = { 1, 2, 3 }; 275 template<> char var<char>[] = "hello"; 276 template<typename T> char var<T*>[] = "pointer"; 277 278 static_assert(sizeof(var<int>) == 12, ""); 279 static_assert(sizeof(var<char>) == 6, ""); 280 static_assert(sizeof(var<void*>) == 8, ""); 281 282 template<typename...> struct tuple; 283 284 template<typename T> struct A { 285 template<typename U> static T x[]; 286 template<typename U> static T y[]; 287 288 template<typename...U> static T y<tuple<U...> >[]; 289 }; 290 291 int *use_before_definition = A<int>::x<char>; 292 template<typename T> template<typename U> T A<T>::x[sizeof(U)]; 293 static_assert(sizeof(A<int>::x<char>) == 4, ""); 294 295 template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... }; 296 static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, ""); 297 } 298 299 namespace bad_reference { 300 struct S { 301 template<typename T> static int A; // expected-note 4{{here}} 302 }; 303 304 template<typename T> void f() { 305 typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::template A'}} 306 } 307 template<typename T> void g() { 308 T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::template A'}} 309 } 310 template<typename T> void h() { 311 class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::template A'}} 312 } 313 314 template<typename T> 315 struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::template A'}} 316 317 template void f<S>(); // expected-note {{in instantiation of}} 318 template void g<S>(); // expected-note {{in instantiation of}} 319 template void h<S>(); // expected-note {{in instantiation of}} 320 template struct X<S>; // expected-note {{in instantiation of}} 321 } 322 } 323 324 namespace in_nested_classes { 325 // TODO: 326 } 327 328 namespace bitfield { 329 struct S { 330 template <int I> 331 static int f : I; // expected-error {{static member 'f' cannot be a bit-field}} 332 }; 333 } 334 335 namespace b20896909 { 336 // This used to crash. 337 template<typename T> struct helper {}; 338 template<typename T> class A { 339 template <typename> static helper<typename T::error> x; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} 340 }; 341 void test() { 342 A<int> ai; // expected-note {{in instantiation of}} 343 } 344 } 345 namespace member_access_is_ok { 346 #ifdef CPP1Y 347 namespace ns1 { 348 struct A { 349 template<class T, T N> constexpr static T Var = N; 350 }; 351 static_assert(A{}.Var<int,5> == 5,""); 352 } // end ns1 353 #endif // CPP1Y 354 355 namespace ns2 { 356 template<class T> struct A { 357 template<class U, T N, U M> static T&& Var; 358 }; 359 template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M); 360 int *AV = &A<int>().Var<char, 5, 'A'>; 361 362 } //end ns2 363 } // end ns member_access_is_ok 364 365 #ifdef CPP1Y 366 namespace PR24473 { 367 struct Value 368 { 369 template<class T> 370 static constexpr T value = 0; 371 }; 372 373 template<typename TValue> 374 struct Something 375 { 376 void foo() { 377 static_assert(TValue::template value<int> == 0, ""); // error 378 } 379 }; 380 381 int main() { 382 Something<Value>{}.foo(); 383 return 0; 384 } 385 386 } // end ns PR24473 387 #endif // CPP1Y 388 389 namespace dependent_static_var_template { 390 struct A { 391 template<int = 0> static int n; // expected-note 2{{here}} 392 }; 393 int &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}} 394 395 template<typename T> 396 int &f() { return T::template n; } // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}} 397 int &s = f<A>(); // expected-note {{instantiation of}} 398 399 namespace B { 400 template<int = 0> static int n; // expected-note {{here}} 401 } 402 int &t = B::template n; // expected-error {{use of variable template 'B::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}} 403 404 struct C { 405 template <class T> static T G; 406 }; 407 template<class T> T C::G = T(6); 408 409 template <class T> T F() { 410 C c; 411 return c.G<T>; 412 } 413 414 int cf() { return F<int>(); } 415 } 416 417 #ifndef PRECXX11 418 namespace template_vars_in_template { 419 template <int> struct TakesInt {}; 420 421 template <class T2> 422 struct S { 423 template <class T1> 424 static constexpr int v = 42; 425 426 template <class T> 427 void mf() { 428 constexpr int val = v<T>; 429 } 430 431 void mf2() { 432 constexpr int val = v<char>; 433 TakesInt<val> ti; 434 (void)ti.x; // expected-error{{no member named 'x' in 'template_vars_in_template::TakesInt<42>'}} 435 } 436 }; 437 438 void useit() { 439 S<int> x; 440 x.mf<double>(); 441 x.mf2(); // expected-note{{in instantiation of member function 'template_vars_in_template::S<int>::mf2' requested here}} 442 } 443 } 444 #endif 445