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