xref: /aosp_15_r20/external/clang/test/SemaCXX/friend.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
2*67e74705SXin Li 
3*67e74705SXin Li friend class A; // expected-error {{'friend' used outside of class}}
f()4*67e74705SXin Li void f() { friend class A; } // expected-error {{'friend' used outside of class}}
5*67e74705SXin Li class C { friend class A; };
f()6*67e74705SXin Li class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}}
7*67e74705SXin Li 
8*67e74705SXin Li // PR5760
9*67e74705SXin Li namespace test0 {
10*67e74705SXin Li   namespace ns {
11*67e74705SXin Li     void f(int);
12*67e74705SXin Li   }
13*67e74705SXin Li 
14*67e74705SXin Li   struct A {
15*67e74705SXin Li     friend void ns::f(int a);
16*67e74705SXin Li   };
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li // Test derived from LLVM's Registry.h
20*67e74705SXin Li namespace test1 {
21*67e74705SXin Li   template <class T> struct Outer {
22*67e74705SXin Li     void foo(T);
23*67e74705SXin Li     struct Inner {
24*67e74705SXin Li       friend void Outer::foo(T);
25*67e74705SXin Li     };
26*67e74705SXin Li   };
27*67e74705SXin Li 
test()28*67e74705SXin Li   void test() {
29*67e74705SXin Li     (void) Outer<int>::Inner();
30*67e74705SXin Li   }
31*67e74705SXin Li }
32*67e74705SXin Li 
33*67e74705SXin Li // PR5476
34*67e74705SXin Li namespace test2 {
35*67e74705SXin Li   namespace foo {
36*67e74705SXin Li     void Func(int x);
37*67e74705SXin Li   }
38*67e74705SXin Li 
39*67e74705SXin Li   class Bar {
40*67e74705SXin Li     friend void ::test2::foo::Func(int x);
41*67e74705SXin Li   };
42*67e74705SXin Li }
43*67e74705SXin Li 
44*67e74705SXin Li // PR5134
45*67e74705SXin Li namespace test3 {
46*67e74705SXin Li   class Foo {
getInt(int inInt=0)47*67e74705SXin Li     friend const int getInt(int inInt = 0) {}
48*67e74705SXin Li 
49*67e74705SXin Li   };
50*67e74705SXin Li }
51*67e74705SXin Li 
52*67e74705SXin Li namespace test4 {
53*67e74705SXin Li   class T4A {
54*67e74705SXin Li     friend class T4B;
55*67e74705SXin Li 
56*67e74705SXin Li   public:
57*67e74705SXin Li     T4A(class T4B *);
58*67e74705SXin Li 
59*67e74705SXin Li   protected:
60*67e74705SXin Li     T4B *mB;          // error here
61*67e74705SXin Li   };
62*67e74705SXin Li 
63*67e74705SXin Li   class T4B {};
64*67e74705SXin Li }
65*67e74705SXin Li 
66*67e74705SXin Li namespace rdar8529993 {
67*67e74705SXin Li struct A { ~A(); };
68*67e74705SXin Li 
69*67e74705SXin Li struct B : A
70*67e74705SXin Li {
71*67e74705SXin Li   template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}}
72*67e74705SXin Li };
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li // PR7915
76*67e74705SXin Li namespace test5 {
77*67e74705SXin Li   struct A;
78*67e74705SXin Li   struct A1 { friend void A(); };
79*67e74705SXin Li 
80*67e74705SXin Li   struct B { friend void B(); };
81*67e74705SXin Li }
82*67e74705SXin Li 
83*67e74705SXin Li // PR8479
84*67e74705SXin Li namespace test6_1 {
85*67e74705SXin Li   class A {
86*67e74705SXin Li    public:
87*67e74705SXin Li    private:
88*67e74705SXin Li     friend class vectorA;
A()89*67e74705SXin Li     A() {}
90*67e74705SXin Li   };
91*67e74705SXin Li   class vectorA {
92*67e74705SXin Li    public:
vectorA(int i,const A & t=A ())93*67e74705SXin Li     vectorA(int i, const A& t = A()) {}
94*67e74705SXin Li   };
f()95*67e74705SXin Li   void f() {
96*67e74705SXin Li     vectorA v(1);
97*67e74705SXin Li   }
98*67e74705SXin Li }
99*67e74705SXin Li namespace test6_2 {
100*67e74705SXin Li   template<class T>
101*67e74705SXin Li   class vector {
102*67e74705SXin Li    public:
vector(int i,const T & t=T ())103*67e74705SXin Li     vector(int i, const T& t = T()) {}
104*67e74705SXin Li   };
105*67e74705SXin Li   class A {
106*67e74705SXin Li    public:
107*67e74705SXin Li    private:
108*67e74705SXin Li     friend class vector<A>;
A()109*67e74705SXin Li     A() {}
110*67e74705SXin Li   };
f()111*67e74705SXin Li   void f() {
112*67e74705SXin Li     vector<A> v(1);
113*67e74705SXin Li   }
114*67e74705SXin Li }
115*67e74705SXin Li namespace test6_3 {
116*67e74705SXin Li   template<class T>
117*67e74705SXin Li   class vector {
118*67e74705SXin Li    public:
vector(int i)119*67e74705SXin Li     vector(int i) {}
f(const T & t=T ())120*67e74705SXin Li     void f(const T& t = T()) {}
121*67e74705SXin Li   };
122*67e74705SXin Li   class A {
123*67e74705SXin Li    public:
124*67e74705SXin Li    private:
125*67e74705SXin Li     friend void vector<A>::f(const A&);
A()126*67e74705SXin Li     A() {}
127*67e74705SXin Li   };
f()128*67e74705SXin Li   void f() {
129*67e74705SXin Li     vector<A> v(1);
130*67e74705SXin Li     v.f();
131*67e74705SXin Li   }
132*67e74705SXin Li }
133*67e74705SXin Li 
134*67e74705SXin Li namespace test7 {
135*67e74705SXin Li   extern "C" {
136*67e74705SXin Li     class X {
test7_f()137*67e74705SXin Li       friend int test7_f() { return 42; }
138*67e74705SXin Li     };
139*67e74705SXin Li   }
140*67e74705SXin Li }
141*67e74705SXin Li 
142*67e74705SXin Li // PR15485
143*67e74705SXin Li namespace test8 {
144*67e74705SXin Li   namespace ns1 {
145*67e74705SXin Li     namespace ns2 {
146*67e74705SXin Li       template<class T> void f(T t); // expected-note {{target of using declaration}}
147*67e74705SXin Li     }
148*67e74705SXin Li     using ns2::f; // expected-note {{using declaration}}
149*67e74705SXin Li   }
150*67e74705SXin Li   struct A { void f(); }; // expected-note 2{{target of using declaration}}
151*67e74705SXin Li   struct B : public A { using A::f; }; // expected-note {{using declaration}}
152*67e74705SXin Li   template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}}
153*67e74705SXin Li   struct X {
154*67e74705SXin Li     template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}}
155*67e74705SXin Li     friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
156*67e74705SXin Li     friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}}
157*67e74705SXin Li   };
158*67e74705SXin Li }
159*67e74705SXin Li 
160*67e74705SXin Li // PR16423
161*67e74705SXin Li namespace test9 {
162*67e74705SXin Li   class C {
163*67e74705SXin Li   };
164*67e74705SXin Li   struct A {
ftest9::A165*67e74705SXin Li     friend void C::f(int, int, int) {}  // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}}
166*67e74705SXin Li   };
167*67e74705SXin Li }
168*67e74705SXin Li 
169*67e74705SXin Li namespace test10 {
170*67e74705SXin Li   struct X {};
171*67e74705SXin Li   extern void f10_a();
172*67e74705SXin Li   extern void f10_a(X);
173*67e74705SXin Li   struct A {
174*67e74705SXin Li     friend void f10_a();
175*67e74705SXin Li     friend void f10_b();
176*67e74705SXin Li     friend void f10_c();
177*67e74705SXin Li     friend void f10_d();
178*67e74705SXin Li     friend void f10_a(X);
179*67e74705SXin Li     friend void f10_b(X);
180*67e74705SXin Li     friend void f10_c(X);
181*67e74705SXin Li     friend void f10_d(X);
182*67e74705SXin Li   };
183*67e74705SXin Li   extern void f10_b();
184*67e74705SXin Li   extern void f10_b(X);
185*67e74705SXin Li   struct B {
186*67e74705SXin Li     friend void f10_a();
187*67e74705SXin Li     friend void f10_b();
188*67e74705SXin Li     friend void f10_c();
189*67e74705SXin Li     friend void f10_d();
190*67e74705SXin Li     friend void f10_a(X);
191*67e74705SXin Li     friend void f10_b(X);
192*67e74705SXin Li     friend void f10_c(X);
193*67e74705SXin Li     friend void f10_d(X);
194*67e74705SXin Li   };
195*67e74705SXin Li   extern void f10_c();
196*67e74705SXin Li   extern void f10_c(X);
197*67e74705SXin Li 
198*67e74705SXin Li   // FIXME: Give a better diagnostic for the case where a function exists but is
199*67e74705SXin Li   // not visible.
g(X x)200*67e74705SXin Li   void g(X x) {
201*67e74705SXin Li     f10_a();
202*67e74705SXin Li     f10_b();
203*67e74705SXin Li     f10_c();
204*67e74705SXin Li     f10_d(); // expected-error {{undeclared identifier}}
205*67e74705SXin Li 
206*67e74705SXin Li     ::test10::f10_a();
207*67e74705SXin Li     ::test10::f10_b();
208*67e74705SXin Li     ::test10::f10_c();
209*67e74705SXin Li     ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
210*67e74705SXin Li 
211*67e74705SXin Li     f10_a(x);
212*67e74705SXin Li     f10_b(x);
213*67e74705SXin Li     f10_c(x);
214*67e74705SXin Li     f10_d(x); // PR16597: expected-error {{undeclared identifier}}
215*67e74705SXin Li 
216*67e74705SXin Li     ::test10::f10_a(x);
217*67e74705SXin Li     ::test10::f10_b(x);
218*67e74705SXin Li     ::test10::f10_c(x);
219*67e74705SXin Li     ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
220*67e74705SXin Li   }
221*67e74705SXin Li 
222*67e74705SXin Li   struct Y : X {
223*67e74705SXin Li     friend void f10_d();
224*67e74705SXin Li     friend void f10_d(X);
225*67e74705SXin Li   };
226*67e74705SXin Li 
227*67e74705SXin Li   struct Z {
228*67e74705SXin Li     operator X();
229*67e74705SXin Li     friend void f10_d();
230*67e74705SXin Li     friend void f10_d(X);
231*67e74705SXin Li   };
232*67e74705SXin Li 
g(X x,Y y,Z z)233*67e74705SXin Li   void g(X x, Y y, Z z) {
234*67e74705SXin Li     f10_d(); // expected-error {{undeclared identifier}}
235*67e74705SXin Li     ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
236*67e74705SXin Li 
237*67e74705SXin Li     // f10_d is visible to ADL in the second and third cases.
238*67e74705SXin Li     f10_d(x); // expected-error {{undeclared identifier}}
239*67e74705SXin Li     f10_d(y);
240*67e74705SXin Li     f10_d(z);
241*67e74705SXin Li 
242*67e74705SXin Li     // No ADL here.
243*67e74705SXin Li     ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
244*67e74705SXin Li     ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
245*67e74705SXin Li     ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
246*67e74705SXin Li   }
247*67e74705SXin Li 
local_externs(X x,Y y)248*67e74705SXin Li   void local_externs(X x, Y y) {
249*67e74705SXin Li     extern void f10_d();
250*67e74705SXin Li     extern void f10_d(X);
251*67e74705SXin Li     f10_d();
252*67e74705SXin Li     f10_d(x);
253*67e74705SXin Li     // FIXME: This lookup should fail, because the local extern declaration
254*67e74705SXin Li     // should suppress ADL.
255*67e74705SXin Li     f10_d(y);
256*67e74705SXin Li     {
257*67e74705SXin Li       int f10_d;
258*67e74705SXin Li       f10_d(); // expected-error {{not a function}}
259*67e74705SXin Li       f10_d(x); // expected-error {{not a function}}
260*67e74705SXin Li       f10_d(y); // expected-error {{not a function}}
261*67e74705SXin Li     }
262*67e74705SXin Li   }
263*67e74705SXin Li 
i(X x,Y y)264*67e74705SXin Li   void i(X x, Y y) {
265*67e74705SXin Li     f10_d(); // expected-error {{undeclared identifier}}
266*67e74705SXin Li     f10_d(x); // expected-error {{undeclared identifier}}
267*67e74705SXin Li     f10_d(y);
268*67e74705SXin Li   }
269*67e74705SXin Li 
270*67e74705SXin Li   struct C {
271*67e74705SXin Li     friend void f10_d();
272*67e74705SXin Li     friend void f10_d(X);
273*67e74705SXin Li   };
274*67e74705SXin Li 
j(X x,Y y)275*67e74705SXin Li   void j(X x, Y y) {
276*67e74705SXin Li     f10_d(); // expected-error {{undeclared identifier}}
277*67e74705SXin Li     f10_d(x); // expected-error {{undeclared identifier}}
278*67e74705SXin Li     f10_d(y);
279*67e74705SXin Li   }
280*67e74705SXin Li 
281*67e74705SXin Li   extern void f10_d();
282*67e74705SXin Li   extern void f10_d(X);
k(X x,Y y,Z z)283*67e74705SXin Li   void k(X x, Y y, Z z) {
284*67e74705SXin Li     // All OK now.
285*67e74705SXin Li     f10_d();
286*67e74705SXin Li     f10_d(x);
287*67e74705SXin Li     ::test10::f10_d();
288*67e74705SXin Li     ::test10::f10_d(x);
289*67e74705SXin Li     ::test10::f10_d(y);
290*67e74705SXin Li     ::test10::f10_d(z);
291*67e74705SXin Li   }
292*67e74705SXin Li }
293*67e74705SXin Li 
294*67e74705SXin Li namespace test11 {
295*67e74705SXin Li   class __attribute__((visibility("hidden"))) B;
296*67e74705SXin Li 
297*67e74705SXin Li   class A {
298*67e74705SXin Li     friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
299*67e74705SXin Li   };
300*67e74705SXin Li }
301*67e74705SXin Li 
302*67e74705SXin Li namespace pr21851 {
303*67e74705SXin Li // PR21851 was a problem where we assumed that when the friend function redecl
304*67e74705SXin Li // lookup found a C++ method, it would necessarily have a qualifier. Below we
305*67e74705SXin Li // have some test cases where unqualified lookup finds C++ methods without using
306*67e74705SXin Li // qualifiers. Unfortunately, we can't exercise the case of an access check
307*67e74705SXin Li // failure because nested classes always have access to the members of outer
308*67e74705SXin Li // classes.
309*67e74705SXin Li 
friend_own_method()310*67e74705SXin Li void friend_own_method() {
311*67e74705SXin Li   class A {
312*67e74705SXin Li     void m() {}
313*67e74705SXin Li     friend void m();
314*67e74705SXin Li   };
315*67e74705SXin Li }
316*67e74705SXin Li 
friend_enclosing_method()317*67e74705SXin Li void friend_enclosing_method() {
318*67e74705SXin Li   class A;
319*67e74705SXin Li   class C {
320*67e74705SXin Li     int p;
321*67e74705SXin Li     friend class A;
322*67e74705SXin Li   };
323*67e74705SXin Li   class A {
324*67e74705SXin Li     void enclosing_friend() {
325*67e74705SXin Li       (void)b->p;
326*67e74705SXin Li       (void)c->p;
327*67e74705SXin Li     }
328*67e74705SXin Li     class B {
329*67e74705SXin Li       void b(A *a) {
330*67e74705SXin Li         (void)a->c->p;
331*67e74705SXin Li       }
332*67e74705SXin Li       int p;
333*67e74705SXin Li       friend void enclosing_friend();
334*67e74705SXin Li     };
335*67e74705SXin Li     B *b;
336*67e74705SXin Li     C *c;
337*67e74705SXin Li   };
338*67e74705SXin Li }
339*67e74705SXin Li 
friend_file_func()340*67e74705SXin Li static auto friend_file_func() {
341*67e74705SXin Li   extern void file_scope_friend();
342*67e74705SXin Li   class A {
343*67e74705SXin Li     int p;
344*67e74705SXin Li     friend void file_scope_friend();
345*67e74705SXin Li   };
346*67e74705SXin Li   return A();
347*67e74705SXin Li }
348*67e74705SXin Li 
file_scope_friend()349*67e74705SXin Li void file_scope_friend() {
350*67e74705SXin Li   auto a = friend_file_func();
351*67e74705SXin Li   (void)a.p;
352*67e74705SXin Li }
353*67e74705SXin Li }
354*67e74705SXin Li 
355*67e74705SXin Li template<typename T>
356*67e74705SXin Li struct X_pr6954 {
357*67e74705SXin Li   operator int();
358*67e74705SXin Li   friend void f_pr6954(int x);
359*67e74705SXin Li };
360*67e74705SXin Li 
361*67e74705SXin Li int array0_pr6954[sizeof(X_pr6954<int>)];
362*67e74705SXin Li int array1_pr6954[sizeof(X_pr6954<float>)];
363*67e74705SXin Li 
g_pr6954()364*67e74705SXin Li void g_pr6954() {
365*67e74705SXin Li   f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
366*67e74705SXin Li }
367*67e74705SXin Li 
368*67e74705SXin Li namespace tag_redecl {
369*67e74705SXin Li   namespace N {
370*67e74705SXin Li     struct X *p;
371*67e74705SXin Li     namespace {
372*67e74705SXin Li       class K {
373*67e74705SXin Li         friend struct X;
374*67e74705SXin Li       };
375*67e74705SXin Li     }
376*67e74705SXin Li   }
377*67e74705SXin Li   namespace N {
378*67e74705SXin Li     struct X;
379*67e74705SXin Li     X *q = p;
380*67e74705SXin Li   }
381*67e74705SXin Li }
382