brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.1 KiB · e18223d Raw
465 lines · cpp
1// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX112// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s3// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1y -verify -fsyntax-only %s -DCPP1Y4 5#define CONST const6 7#ifdef PRECXX118#define static_assert _Static_assert9#endif10 11class 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 PRECXX1119                                                        // expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}}20#else21                                                        // expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}}22                                                        // expected-note@-5 {{add 'constexpr'}}23#endif24  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 29namespace 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 77namespace 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 undefined102  // 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 definition135    };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 definition142    };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 PRECXX11162namespace 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#endif178 179namespace 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 class227    // templates.228    //229    // [temp.class.spec.mfunc]/2: If the primary member template is explicitly230    // specialized for a given specialization of the enclosing class template,231    // the partial specializations of the member template are ignored232    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're255    // not picking up partial specializations added after the primary template256    // 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 clear258    // 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 implicit266    // 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 'in_class_template::bad_reference::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 'in_class_template::bad_reference::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 'in_class_template::bad_reference::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 'in_class_template::bad_reference::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 324namespace in_nested_classes {325  // TODO:326}327 328namespace bitfield {329struct S {330  template <int I>331  static int f : I; // expected-error {{static member 'f' cannot be a bit-field}}332};333}334 335namespace 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}345namespace member_access_is_ok {346#ifdef CPP1Y347  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 ns1353#endif // CPP1Y354 355namespace 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 ns2363} // end ns member_access_is_ok364 365#ifdef CPP1Y366namespace PR24473 {367struct Value368{369    template<class T>370    static constexpr T value = 0;371};372 373template<typename TValue>374struct Something375{376    void foo() {377        static_assert(TValue::template value<int> == 0, ""); // error378    }379};380 381int main() {382    Something<Value>{}.foo();383    return 0;384}385 386} // end ns PR24473387#endif // CPP1Y388 389namespace 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 'dependent_static_var_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#ifdef CPP1Y417  namespace GH55872 {418    struct s {419      template<typename T>420      static CONST auto f = [] { return T::template g<s>; };421      // expected-note@-1 {{in instantiation of static data member 'dependent_static_var_template::GH55872::t::g' requested here}}422      // expected-note@-2 {{while substituting into a lambda expression here}}423    };424 425    struct t {426      template<typename T>427      static CONST auto g = [] { return T::template f<t>; };428      // expected-error@-1 {{the type of variable template specialization 'f<dependent_static_var_template::GH55872::t>' declared with deduced type 'const auto' depends on itself}}429      // expected-note@-2 {{while substituting into a lambda expression here}}430    };431 432    void test() { s::f<t>()(); } // expected-note {{in instantiation of static data member 'dependent_static_var_template::GH55872::s::f' requested here}}433  }434#endif435}436 437#ifndef PRECXX11438namespace template_vars_in_template {439template <int> struct TakesInt {};440 441template <class T2>442struct S {443  template <class T1>444  static constexpr int v = 42;445 446  template <class T>447  void mf() {448    constexpr int val = v<T>;449  }450 451  void mf2() {452    constexpr int val = v<char>;453    TakesInt<val> ti;454    (void)ti.x; // expected-error{{no member named 'x' in 'template_vars_in_template::TakesInt<42>'}}455  }456};457 458void useit() {459  S<int> x;460  x.mf<double>();461  x.mf2(); // expected-note{{in instantiation of member function 'template_vars_in_template::S<int>::mf2' requested here}}462}463}464#endif465