1 // RUN: %clang_cc1 -std=c++20 -pedantic -verify %s 2 3 struct X { 4 using type = int; 5 static constexpr int value = 1; 6 class tclass {}; 7 }; 8 9 template <typename T> 10 void f() { 11 // it is a qualified name in a type-id-only context (see below), or 12 // [its smallest enclosing [/new/defining/]-type-id is]: 13 // - a new-type-id 14 auto *Ptr = new T::type(); 15 // - a defining-type-id 16 class T::tclass Empty1; 17 T::tclass Empty2; // expected-error{{missing 'typename'}} 18 // - a trailing-return-type 19 auto f()->T::type; 20 // - default argument of a type-parameter of a template [see below] 21 22 // - type-id of a 23 // 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_cast 30 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 39 template void f<X>(); 40 41 // As default argument. 42 template <typename T, typename = T::type> 43 struct DefaultArg {}; 44 45 template struct DefaultArg<X>; 46 47 // it is a decl-specifier of the decl-specifier-seq of a 48 // - simple-declaration or a function-definition in namespace scope 49 template <typename T> 50 T::type VarTemp = 1; 51 52 template int VarTemp<X>; 53 54 template <typename T> 55 T::type FuncDef() { return 1; } 56 57 template int FuncDef<X>(); 58 59 template <typename T> 60 T::type funcDecl(); 61 62 template <typename T> 63 void FuncParam(T::type); // ok, but variable template 64 // expected-error@-1{{variable has incomplete type 'void'}} 65 66 template <typename T> 67 void FuncParam2(const T::type, int); // expected-error{{missing 'typename'}} 68 69 template <typename T> 70 struct MemberDecl { 71 // member-declaration, 72 T::type Member; 73 74 // parameter-declaration in a member-declaration, unless that 75 // parameter-declaration appears in a default argument 76 void NoDefault(T::type); 77 void Default(int A = T::value); 78 }; 79 80 template struct MemberDecl<X>; 81 82 // parameter-declaration in a declarator of a function or function template 83 // declaration where the declarator-id is qualified, unless that 84 // parameter-declaration appears in a default argument, 85 struct QualifiedFunc { 86 template <typename T> 87 void foo(typename T::type); 88 template <typename T> 89 void bar(T::type); 90 }; 91 92 template <typename T> 93 void QualifiedFunc::foo(T::type) {} 94 template <typename T> 95 void QualifiedFunc::bar(typename T::type) {} 96 97 template <typename T> 98 void g() { 99 // parameter-declaration in a lambda-declarator, unless that 100 // parameter-declaration appears in a default argument, or 101 auto Lambda1 = [](T::type) {}; 102 auto Lambda2 = [](int A = T::value) {}; 103 } 104 105 template void g<X>(); 106 107 // parameter-declaration of a (non-type) template-parameter. 108 template <typename T, T::type> 109 void NonTypeArg() {} 110 111 template void NonTypeArg<X, 0>(); 112 113 template <typename T> 114 void f(T::type) {} // expected-error {{missing 'typename'}} 115 116 namespace N { 117 template <typename T> 118 int f(typename T::type); 119 template <typename T> 120 extern int Var; 121 } 122 123 template <typename T> 124 int N::f(T::type); // ok, function 125 template <typename T> 126 int N::Var(T::value); // ok, variable 127 128 int h() { 129 return N::f<X>(10) + N::Var<X>; 130 } 131 132 namespace 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 137 template <typename T> 138 int NN::f(T::type); // expected-error{{redefinition of 'f' as different kind of symbol}} 139 140 template <auto V> 141 struct videntity { 142 static constexpr auto value = V; 143 }; 144 145 template <typename T, 146 bool = T::value, 147 bool = bool(T::value), 148 bool = videntity<bool(T::value)>::value> 149 void f(int = T::value) {} 150 151 template <typename> int test() = delete; 152 template <auto> int test(); 153 154 template <typename T> 155 int Test = test<int(T::value)>(); 156 template int Test<X>; 157 158 template<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 164 template<typename T> 165 struct C { 166 C(T::type); // implicit typename context 167 friend C (T::fn)(); // not implicit typename context, declarator-id of friend declaration 168 C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type 169 }; 170 171 template <typename T> 172 C<T>::C(T::type) {} 173 174 namespace GH63119 { 175 struct X { 176 X(int); 177 X(auto); 178 void f(int); 179 }; 180 template<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 189 namespace GH113324 { 190 template <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 195 template <class T> using alias = int; 196 template <typename T> struct S2 { 197 // FIXME: We miss diagnosing the default argument instantiation failure 198 // (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 202 void test() { 203 f1(S1<>{}); 204 f2(S1<>{}); 205 f3(S2<void>()); 206 } 207 } // namespace GH113324 208