brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 9dbdd23 Raw
208 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -pedantic -verify %s2 3struct X {4  using type = int;5  static constexpr int value = 1;6  class tclass {};7};8 9template <typename T>10void f() {11  // it is a qualified name in a type-id-only context (see below), or12  // [its smallest enclosing [/new/defining/]-type-id is]:13  // - a new-type-id14  auto *Ptr = new T::type();15  // - a defining-type-id16  class T::tclass Empty1;17  T::tclass Empty2; // expected-error{{missing 'typename'}}18  // - a trailing-return-type19  auto f()->T::type;20  // - default argument of a type-parameter of a template [see below]21 22  // - type-id of a23  // static_cast,24  auto StaticCast = static_cast<T::type>(1.2);25  // const_cast,26  const auto *ConstCast = const_cast<const T::type *>(Ptr);27  // reinterpret_cast,28  int ReinterpretCast = reinterpret_cast<T::type>(4);29  // dynamic_cast30  struct B {31    virtual ~B() = default;32  };33  struct D : T::tclass {};34  auto *Base = dynamic_cast<T::tclass *>(new B);35 36  T::type Invalid; // expected-error{{missing 'typename'}}37}38 39template void f<X>();40 41// As default argument.42template <typename T, typename = T::type>43struct DefaultArg {};44 45template struct DefaultArg<X>;46 47// it is a decl-specifier of the decl-specifier-seq of a48// - simple-declaration or a function-definition in namespace scope49template <typename T>50T::type VarTemp = 1;51 52template int VarTemp<X>;53 54template <typename T>55T::type FuncDef() { return 1; }56 57template int FuncDef<X>();58 59template <typename T>60T::type funcDecl();61 62template <typename T>63void FuncParam(T::type); // ok, but variable template64// expected-error@-1{{variable has incomplete type 'void'}}65 66template <typename T>67void FuncParam2(const T::type, int); // expected-error{{missing 'typename'}}68 69template <typename T>70struct MemberDecl {71  // member-declaration,72  T::type Member;73 74  // parameter-declaration in a member-declaration, unless that75  // parameter-declaration appears in a default argument76  void NoDefault(T::type);77  void Default(int A = T::value);78};79 80template struct MemberDecl<X>;81 82// parameter-declaration in a declarator of a function or function template83// declaration where the declarator-id is qualified, unless that84// parameter-declaration appears in a default argument,85struct QualifiedFunc {86  template <typename T>87  void foo(typename T::type);88  template <typename T>89  void bar(T::type);90};91 92template <typename T>93void QualifiedFunc::foo(T::type) {}94template <typename T>95void QualifiedFunc::bar(typename T::type) {}96 97template <typename T>98void g() {99  // parameter-declaration in a lambda-declarator, unless that100  // parameter-declaration appears in a default argument, or101  auto Lambda1 = [](T::type) {};102  auto Lambda2 = [](int A = T::value) {};103}104 105template void g<X>();106 107// parameter-declaration of a (non-type) template-parameter.108template <typename T, T::type>109void NonTypeArg() {}110 111template void NonTypeArg<X, 0>();112 113template <typename T>114void f(T::type) {} // expected-error {{missing 'typename'}}115 116namespace N {117  template <typename T>118  int f(typename T::type);119  template <typename T>120  extern int Var;121}122 123template <typename T>124int N::f(T::type); // ok, function125template <typename T>126int N::Var(T::value); // ok, variable127 128int h() {129  return N::f<X>(10) + N::Var<X>;130}131 132namespace NN {133  inline namespace A { template <typename T> int f(typename T::type); } // expected-note{{previous definition is here}}134  inline namespace B { template <typename T> int f(T::type); }135}136 137template <typename T>138int NN::f(T::type); // expected-error{{redefinition of 'f' as different kind of symbol}}139 140template <auto V>141struct videntity {142  static constexpr auto value = V;143};144 145template <typename T,146    bool = T::value,147    bool = bool(T::value),148    bool = videntity<bool(T::value)>::value>149void f(int = T::value) {}150 151template <typename> int test() = delete;152template <auto> int test();153 154template <typename T>155int Test = test<int(T::value)>();156template int Test<X>;157 158template<typename T> struct A {159  enum E : T::type {}; // expected-error{{missing 'typename'}}160  operator T::type() {} // expected-error{{missing 'typename'}}161  void f() { this->operator T::type(); } // expected-error{{missing 'typename'}}162};163 164template<typename T>165struct C {166  C(T::type); // implicit typename context167  friend C (T::fn)(); // not implicit typename context, declarator-id of friend declaration168  C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type169};170 171template <typename T>172C<T>::C(T::type) {}173 174namespace GH63119 {175struct X {176    X(int);177    X(auto);178    void f(int);179};180template<typename T> struct S {181  friend X::X(T::type);182  friend X::X(T::type = (int)(void(*)(typename T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}}183  friend X::X(T::type = (int)(void(*)(T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}} \184                                                           // expected-error {{expected expression}}185  friend void X::f(T::type);186};187}188 189namespace GH113324 {190template <typename = int> struct S1 {191  friend void f1(S1, int = 0); // expected-error {{friend declaration specifying a default argument must be a definition}}192  friend void f2(S1 a, S1 = decltype(a){}); // expected-error {{friend declaration specifying a default argument must be a definition}}193};194 195template <class T> using alias = int;196template <typename T> struct S2 {197  // FIXME: We miss diagnosing the default argument instantiation failure198  // (forming reference to void)199  friend void f3(S2, int a = alias<T &>(1)); // expected-error {{friend declaration specifying a default argument must be a definition}}200};201 202void test() {203  f1(S1<>{});204  f2(S1<>{});205  f3(S2<void>());206}207} // namespace GH113324208