xref: /llvm-project/clang/test/CXX/temp/temp.res/p4.cpp (revision 9daf10ff8f29ba3a88a105aaa9d2379c21b77d35)
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