xref: /aosp_15_r20/external/clang/test/SemaTemplate/friend-template.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li // PR5057
3*67e74705SXin Li namespace test0 {
4*67e74705SXin Li   namespace std {
5*67e74705SXin Li     class X {
6*67e74705SXin Li     public:
7*67e74705SXin Li       template<typename T> friend struct Y;
8*67e74705SXin Li     };
9*67e74705SXin Li   }
10*67e74705SXin Li 
11*67e74705SXin Li   namespace std {
12*67e74705SXin Li     template<typename T> struct Y {};
13*67e74705SXin Li   }
14*67e74705SXin Li }
15*67e74705SXin Li 
16*67e74705SXin Li namespace test1 {
f1(T)17*67e74705SXin Li   template<typename T> void f1(T) { } // expected-note{{here}}
18*67e74705SXin Li 
19*67e74705SXin Li   class X {
20*67e74705SXin Li     template<typename T> friend void f0(T);
21*67e74705SXin Li     template<typename T> friend void f1(T);
22*67e74705SXin Li   };
23*67e74705SXin Li 
f0(T)24*67e74705SXin Li   template<typename T> void f0(T) { }
f1(T)25*67e74705SXin Li   template<typename T> void f1(T) { } // expected-error{{redefinition}}
26*67e74705SXin Li }
27*67e74705SXin Li 
28*67e74705SXin Li // PR4768
29*67e74705SXin Li namespace test2 {
30*67e74705SXin Li   template<typename T> struct X0 {
31*67e74705SXin Li     template<typename U> friend struct X0;
32*67e74705SXin Li   };
33*67e74705SXin Li 
34*67e74705SXin Li   template<typename T> struct X0<T*> {
35*67e74705SXin Li     template<typename U> friend struct X0;
36*67e74705SXin Li   };
37*67e74705SXin Li 
38*67e74705SXin Li   template<> struct X0<int> {
39*67e74705SXin Li     template<typename U> friend struct X0;
40*67e74705SXin Li   };
41*67e74705SXin Li 
42*67e74705SXin Li   template<typename T> struct X1 {
43*67e74705SXin Li     template<typename U> friend void f2(U);
44*67e74705SXin Li     template<typename U> friend void f3(U);
45*67e74705SXin Li   };
46*67e74705SXin Li 
47*67e74705SXin Li   template<typename U> void f2(U);
48*67e74705SXin Li 
49*67e74705SXin Li   X1<int> x1i;
50*67e74705SXin Li   X0<int*> x0ip;
51*67e74705SXin Li 
52*67e74705SXin Li   template<> void f2(int);
53*67e74705SXin Li 
54*67e74705SXin Li   // FIXME: Should this declaration of f3 be required for the specialization of
55*67e74705SXin Li   // f3<int> (further below) to work? GCC and EDG don't require it, we do...
56*67e74705SXin Li   template<typename U> void f3(U);
57*67e74705SXin Li 
58*67e74705SXin Li   template<> void f3(int);
59*67e74705SXin Li }
60*67e74705SXin Li 
61*67e74705SXin Li // PR5332
62*67e74705SXin Li namespace test3 {
63*67e74705SXin Li   template <typename T> class Foo {
64*67e74705SXin Li     template <typename U>
65*67e74705SXin Li     friend class Foo;
66*67e74705SXin Li   };
67*67e74705SXin Li 
68*67e74705SXin Li   Foo<int> foo;
69*67e74705SXin Li 
70*67e74705SXin Li   template<typename T, T Value> struct X2a;
71*67e74705SXin Li 
72*67e74705SXin Li   template<typename T, int Size> struct X2b;
73*67e74705SXin Li 
74*67e74705SXin Li   template<typename T>
75*67e74705SXin Li   class X3 {
76*67e74705SXin Li     template<typename U, U Value> friend struct X2a;
77*67e74705SXin Li 
78*67e74705SXin Li     // FIXME: the redeclaration note ends up here because redeclaration
79*67e74705SXin Li     // lookup ends up finding the friend target from X3<int>.
80*67e74705SXin Li     template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
81*67e74705SXin Li       // expected-note {{previous non-type template parameter with type 'int' is here}}
82*67e74705SXin Li   };
83*67e74705SXin Li 
84*67e74705SXin Li   X3<int> x3i; // okay
85*67e74705SXin Li 
86*67e74705SXin Li   X3<long> x3l; // expected-note {{in instantiation}}
87*67e74705SXin Li }
88*67e74705SXin Li 
89*67e74705SXin Li // PR5716
90*67e74705SXin Li namespace test4 {
91*67e74705SXin Li   template<typename> struct A {
92*67e74705SXin Li     template<typename T> friend void f(const A<T>&);
93*67e74705SXin Li   };
94*67e74705SXin Li 
f(const A<T> &)95*67e74705SXin Li   template<typename T> void f(const A<T>&) {
96*67e74705SXin Li     int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
97*67e74705SXin Li   }
98*67e74705SXin Li 
f()99*67e74705SXin Li   void f() {
100*67e74705SXin Li     f(A<int>()); // expected-note {{in instantiation of function template specialization}}
101*67e74705SXin Li   }
102*67e74705SXin Li }
103*67e74705SXin Li 
104*67e74705SXin Li namespace test5 {
105*67e74705SXin Li   class outer {
106*67e74705SXin Li     class foo;
107*67e74705SXin Li     template <typename T> friend struct cache;
108*67e74705SXin Li   };
109*67e74705SXin Li   class outer::foo {
110*67e74705SXin Li     template <typename T> friend struct cache;
111*67e74705SXin Li   };
112*67e74705SXin Li }
113*67e74705SXin Li 
114*67e74705SXin Li // PR6022
115*67e74705SXin Li namespace PR6022 {
116*67e74705SXin Li   template <class T1, class T2 , class T3  > class A;
117*67e74705SXin Li 
118*67e74705SXin Li   namespace inner {
119*67e74705SXin Li     template<class T1, class T2, class T3, class T>
120*67e74705SXin Li     A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
121*67e74705SXin Li   }
122*67e74705SXin Li 
123*67e74705SXin Li   template<class T1, class T2, class T3>
124*67e74705SXin Li   class A {
125*67e74705SXin Li     template<class U1, class U2, class U3, class T>
126*67e74705SXin Li     friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
127*67e74705SXin Li   };
128*67e74705SXin Li }
129*67e74705SXin Li 
130*67e74705SXin Li namespace FriendTemplateDefinition {
131*67e74705SXin Li   template<unsigned > struct int_c { };
132*67e74705SXin Li 
133*67e74705SXin Li   template<typename T>
134*67e74705SXin Li   struct X {
135*67e74705SXin Li     template<unsigned N>
f(X,int_c<N>)136*67e74705SXin Li     friend void f(X, int_c<N>) {
137*67e74705SXin Li       int value = N;
138*67e74705SXin Li     };
139*67e74705SXin Li   };
140*67e74705SXin Li 
test_X(X<int> x,int_c<5> i5)141*67e74705SXin Li   void test_X(X<int> x, int_c<5> i5) {
142*67e74705SXin Li     f(x, i5);
143*67e74705SXin Li   }
144*67e74705SXin Li }
145*67e74705SXin Li 
146*67e74705SXin Li namespace PR7013a {
147*67e74705SXin Li   template<class > struct X0
148*67e74705SXin Li   {
149*67e74705SXin Li     typedef int type;
150*67e74705SXin Li   };
151*67e74705SXin Li   template<typename > struct X1
152*67e74705SXin Li   {
153*67e74705SXin Li   };
154*67e74705SXin Li   template<typename , typename T> struct X2
155*67e74705SXin Li   {
156*67e74705SXin Li     typename T::type e;
157*67e74705SXin Li   };
158*67e74705SXin Li   namespace N
159*67e74705SXin Li   {
160*67e74705SXin Li     template <typename = int, typename = X1<int> > struct X3
161*67e74705SXin Li     {
162*67e74705SXin Li       template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
163*67e74705SXin Li     };
op(X2<Ch,Tr> &,B)164*67e74705SXin Li     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
165*67e74705SXin Li     {
166*67e74705SXin Li       X2<int, Tr> s;
167*67e74705SXin Li     }
168*67e74705SXin Li   }
n()169*67e74705SXin Li   int n()
170*67e74705SXin Li   {
171*67e74705SXin Li     X2<int, X0<int> > ngs;
172*67e74705SXin Li     N::X3<> b;
173*67e74705SXin Li     op(ngs, b);
174*67e74705SXin Li     return 0;
175*67e74705SXin Li   }
176*67e74705SXin Li }
177*67e74705SXin Li 
178*67e74705SXin Li namespace PR7013b {
179*67e74705SXin Li   template<class > struct X0
180*67e74705SXin Li   {
181*67e74705SXin Li     typedef int type;
182*67e74705SXin Li   };
183*67e74705SXin Li   template<typename > struct X1
184*67e74705SXin Li   {
185*67e74705SXin Li   };
186*67e74705SXin Li   template<typename , typename T> struct X2
187*67e74705SXin Li   {
188*67e74705SXin Li     typename T::type e;
189*67e74705SXin Li   };
190*67e74705SXin Li   namespace N
191*67e74705SXin Li   {
192*67e74705SXin Li     template <typename = X1<int> > struct X3
193*67e74705SXin Li     {
194*67e74705SXin Li       template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
195*67e74705SXin Li     };
op(X2<Ch,Tr> &,B)196*67e74705SXin Li     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
197*67e74705SXin Li     {
198*67e74705SXin Li       X2<int, Tr> s;
199*67e74705SXin Li     }
200*67e74705SXin Li   }
n()201*67e74705SXin Li   int n()
202*67e74705SXin Li   {
203*67e74705SXin Li     X2<int, X0<int> > ngs;
204*67e74705SXin Li     N::X3<> b;
205*67e74705SXin Li     op(ngs, b);
206*67e74705SXin Li     return 0;
207*67e74705SXin Li   }
208*67e74705SXin Li 
209*67e74705SXin Li }
210*67e74705SXin Li 
211*67e74705SXin Li namespace PR8649 {
212*67e74705SXin Li   template<typename T, typename U, unsigned N>
213*67e74705SXin Li   struct X {
214*67e74705SXin Li     template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}}
215*67e74705SXin Li   };
216*67e74705SXin Li 
217*67e74705SXin Li   X<int, float, 7> x;
218*67e74705SXin Li }
219*67e74705SXin Li 
220*67e74705SXin Li // Don't crash, and error on invalid friend type template.
221*67e74705SXin Li namespace friend_type_template_no_tag {
222*67e74705SXin Li   template <typename T> struct S {
223*67e74705SXin Li     template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
224*67e74705SXin Li   };
225*67e74705SXin Li   template struct S<int>;
226*67e74705SXin Li }
227*67e74705SXin Li 
228*67e74705SXin Li namespace PR10660 {
229*67e74705SXin Li   struct A {
230*67e74705SXin Li     template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
231*67e74705SXin Li   };
232*67e74705SXin Li }
233*67e74705SXin Li 
234*67e74705SXin Li namespace rdar11147355 {
235*67e74705SXin Li   template <class T>
236*67e74705SXin Li   struct A {
237*67e74705SXin Li     template <class U> class B;
238*67e74705SXin Li     template <class S> template <class U> friend class A<S>::B; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}}
239*67e74705SXin Li   private:
240*67e74705SXin Li     int n; // expected-note {{here}}
241*67e74705SXin Li   };
242*67e74705SXin Li 
243*67e74705SXin Li   template <class S> template <class U> class A<S>::B {
244*67e74705SXin Li   public:
245*67e74705SXin Li     // FIXME: This should be permitted.
f(A<S * > a)246*67e74705SXin Li     int f(A<S*> a) { return a.n; } // expected-error {{private}}
247*67e74705SXin Li   };
248*67e74705SXin Li 
249*67e74705SXin Li   A<double>::B<double>  ab;
250*67e74705SXin Li   A<double*> a;
251*67e74705SXin Li   int k = ab.f(a); // expected-note {{instantiation of}}
252*67e74705SXin Li }
253*67e74705SXin Li 
254*67e74705SXin Li namespace RedeclUnrelated {
255*67e74705SXin Li   struct S {
256*67e74705SXin Li     int packaged_task;
257*67e74705SXin Li     template<typename> class future {
258*67e74705SXin Li       template<typename> friend class packaged_task;
259*67e74705SXin Li     };
260*67e74705SXin Li     future<void> share;
261*67e74705SXin Li   };
262*67e74705SXin Li }
263*67e74705SXin Li 
264*67e74705SXin Li namespace PR12557 {
265*67e74705SXin Li   template <typename>
266*67e74705SXin Li   struct Foo;
267*67e74705SXin Li 
268*67e74705SXin Li   template <typename Foo_>
269*67e74705SXin Li   struct Bar {
270*67e74705SXin Li     typedef Foo_  Foo; // expected-note {{previous}}
271*67e74705SXin Li 
272*67e74705SXin Li     template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
273*67e74705SXin Li   };
274*67e74705SXin Li 
275*67e74705SXin Li   Bar<int> b;
276*67e74705SXin Li }
277*67e74705SXin Li 
278*67e74705SXin Li namespace PR12585 {
279*67e74705SXin Li   struct A { };
280*67e74705SXin Li   template<typename> struct B {
281*67e74705SXin Li     template<typename> friend class A::does_not_exist; // \
282*67e74705SXin Li      // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
283*67e74705SXin Li   };
284*67e74705SXin Li 
285*67e74705SXin Li   struct C {
286*67e74705SXin Li     template<typename> struct D;
287*67e74705SXin Li   };
288*67e74705SXin Li   template<typename> class E {
289*67e74705SXin Li     int n;
290*67e74705SXin Li     template<typename> friend struct C::D;
291*67e74705SXin Li   };
292*67e74705SXin Li   template<typename T> struct C::D {
fPR12585::C::D293*67e74705SXin Li     int f() {
294*67e74705SXin Li       return E<int>().n;
295*67e74705SXin Li     }
296*67e74705SXin Li   };
297*67e74705SXin Li   int n = C::D<void*>().f();
298*67e74705SXin Li 
299*67e74705SXin Li   struct F {
300*67e74705SXin Li     template<int> struct G;
301*67e74705SXin Li   };
302*67e74705SXin Li   template<typename T> struct H {
303*67e74705SXin Li     // FIXME: As with cases above, the note here is on an unhelpful declaration,
304*67e74705SXin Li     // and should point to the declaration of G within F.
305*67e74705SXin Li     template<T> friend struct F::G; // \
306*67e74705SXin Li       // expected-error {{different type 'char' in template redeclaration}} \
307*67e74705SXin Li       // expected-note {{previous}}
308*67e74705SXin Li   };
309*67e74705SXin Li   H<int> h1; // ok
310*67e74705SXin Li   H<char> h2; // expected-note {{instantiation}}
311*67e74705SXin Li }
312*67e74705SXin Li 
313*67e74705SXin Li // Ensure that we can still instantiate a friend function template
314*67e74705SXin Li // after the friend declaration is instantiated during the delayed
315*67e74705SXin Li // parsing of a member function, but before the friend function has
316*67e74705SXin Li // been parsed.
317*67e74705SXin Li namespace rdar12350696 {
318*67e74705SXin Li   template <class T> struct A {
foordar12350696::A319*67e74705SXin Li     void foo() {
320*67e74705SXin Li       A<int> a;
321*67e74705SXin Li     }
foo(const A<U> & a)322*67e74705SXin Li     template <class U> friend void foo(const A<U> & a) {
323*67e74705SXin Li       int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
324*67e74705SXin Li     }
325*67e74705SXin Li   };
326*67e74705SXin Li 
test()327*67e74705SXin Li   void test() {
328*67e74705SXin Li     A<int> b;
329*67e74705SXin Li     foo(b); // expected-note {{in instantiation}}
330*67e74705SXin Li   }
331*67e74705SXin Li }
332