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 2{{target of using declaration}}
151   struct B : public A { using A::f; }; // expected-note {{using declaration}}
152   template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}}
153   struct X {
154     template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}}
155     friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
156     friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}}
157   };
158 }
159 
160 // PR16423
161 namespace test9 {
162   class C {
163   };
164   struct A {
ftest9::A165     friend void C::f(int, int, int) {}  // expected-error {{friend function definition cannot be qualified with 'C::'}}
166   };
167 }
168 
169 namespace test10 {
170   struct X {};
171   extern void f10_a();
172   extern void f10_a(X);
173   struct A {
174     friend void f10_a();
175     friend void f10_b();
176     friend void f10_c();
177     friend void f10_d();
178     friend void f10_a(X);
179     friend void f10_b(X);
180     friend void f10_c(X);
181     friend void f10_d(X);
182   };
183   extern void f10_b();
184   extern void f10_b(X);
185   struct B {
186     friend void f10_a();
187     friend void f10_b();
188     friend void f10_c();
189     friend void f10_d();
190     friend void f10_a(X);
191     friend void f10_b(X);
192     friend void f10_c(X);
193     friend void f10_d(X);
194   };
195   extern void f10_c();
196   extern void f10_c(X);
197 
198   // FIXME: Give a better diagnostic for the case where a function exists but is
199   // not visible.
g(X x)200   void g(X x) {
201     f10_a();
202     f10_b();
203     f10_c();
204     f10_d(); // expected-error {{undeclared identifier}}
205 
206     ::test10::f10_a();
207     ::test10::f10_b();
208     ::test10::f10_c();
209     ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
210 
211     f10_a(x);
212     f10_b(x);
213     f10_c(x);
214     f10_d(x); // PR16597: expected-error {{undeclared identifier}}
215 
216     ::test10::f10_a(x);
217     ::test10::f10_b(x);
218     ::test10::f10_c(x);
219     ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
220   }
221 
222   struct Y : X {
223     friend void f10_d();
224     friend void f10_d(X);
225   };
226 
227   struct Z {
228     operator X();
229     friend void f10_d();
230     friend void f10_d(X);
231   };
232 
233   struct W {
234     friend void f10_d(W);
235   };
236 
g(X x,Y y,Z z)237   void g(X x, Y y, Z z) {
238     f10_d(); // expected-error {{undeclared identifier}}
239     ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
240 
241     // f10_d is visible to ADL in the second and third cases.
242     f10_d(x); // expected-error {{undeclared identifier}}
243     f10_d(y);
244     f10_d(z);
245 
246     // No ADL here.
247     ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
248     ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
249     ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
250   }
251 
local_externs(W w,X x,Y y)252   void local_externs(W w, X x, Y y) {
253     extern void f10_d(); // expected-note {{candidate}}
254     extern void f10_d(X); // expected-note {{candidate}}
255     f10_d();
256     f10_d(x);
257     f10_d(y);
258     f10_d(w); // expected-error {{no matching}}
259     {
260       int f10_d;
261       f10_d(); // expected-error {{not a function}}
262       f10_d(x); // expected-error {{not a function}}
263       f10_d(y); // expected-error {{not a function}}
264     }
265   }
266 
i(X x,Y y)267   void i(X x, Y y) {
268     f10_d(); // expected-error {{undeclared identifier}}
269     f10_d(x); // expected-error {{undeclared identifier}}
270     f10_d(y);
271   }
272 
273   struct C {
274     friend void f10_d();
275     friend void f10_d(X);
276   };
277 
j(X x,Y y)278   void j(X x, Y y) {
279     f10_d(); // expected-error {{undeclared identifier}}
280     f10_d(x); // expected-error {{undeclared identifier}}
281     f10_d(y);
282   }
283 
284   extern void f10_d();
285   extern void f10_d(X);
k(X x,Y y,Z z)286   void k(X x, Y y, Z z) {
287     // All OK now.
288     f10_d();
289     f10_d(x);
290     ::test10::f10_d();
291     ::test10::f10_d(x);
292     ::test10::f10_d(y);
293     ::test10::f10_d(z);
294   }
295 }
296 
297 namespace test11 {
298   class __attribute__((visibility("hidden"))) B;
299 
300   class A {
301     friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
302   };
303 }
304 
305 namespace pr21851 {
306 // PR21851 was a problem where we assumed that when the friend function redecl
307 // lookup found a C++ method, it would necessarily have a qualifier. Below we
308 // have some test cases where unqualified lookup finds C++ methods without using
309 // qualifiers. Unfortunately, we can't exercise the case of an access check
310 // failure because nested classes always have access to the members of outer
311 // classes.
312 
friend_own_method()313 void friend_own_method() {
314   class A {
315     void m() {}
316     friend void m();
317   };
318 }
319 
friend_enclosing_method()320 void friend_enclosing_method() {
321   class A;
322   class C {
323     int p;
324     friend class A;
325   };
326   class A {
327     void enclosing_friend() {
328       (void)b->p;
329       (void)c->p;
330     }
331     class B {
332       void b(A *a) {
333         (void)a->c->p;
334       }
335       int p;
336       friend void enclosing_friend();
337     };
338     B *b;
339     C *c;
340   };
341 }
342 
friend_file_func()343 static auto friend_file_func() {
344   extern void file_scope_friend();
345   class A {
346     int p;
347     friend void file_scope_friend();
348   };
349   return A();
350 }
351 
file_scope_friend()352 void file_scope_friend() {
353   auto a = friend_file_func();
354   (void)a.p;
355 }
356 }
357 
358 template<typename T>
359 struct X_pr6954 {
360   operator int();
361   friend void f_pr6954(int x);
362 };
363 
364 int array0_pr6954[sizeof(X_pr6954<int>)];
365 int array1_pr6954[sizeof(X_pr6954<float>)];
366 
g_pr6954()367 void g_pr6954() {
368   f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
369 }
370 
371 namespace tag_redecl {
372   namespace N {
373     struct X *p;
374     namespace {
375       class K {
376         friend struct X;
377       };
378     }
379   }
380   namespace N {
381     struct X;
382     X *q = p;
383   }
384 }
385 
386 namespace default_arg {
387   void f();
388   void f(void*); // expected-note {{previous}}
389   struct X {
f(int a,int b=0)390     friend void f(int a, int b = 0) {}
f(void * p=0)391     friend void f(void *p = 0) {} // expected-error {{must be the only}}
392   };
393 }
394 
395 namespace PR33222 {
396   int f();
397   template<typename T> struct X {
398     friend T f();
399   };
400   X<int> xi;
401 
402   int g(); // expected-note {{previous}}
403   template<typename T> struct Y {
404     friend T g(); // expected-error {{return type}}
405   };
406   Y<float> yf; // expected-note {{instantiation}}
407 
408   int h(); // expected-note {{previous}}
409   template<typename T> struct Z {
410     friend T h(); // expected-error {{return type}}
411   };
412   Z<int> zi;
413   Z<float> zf; // expected-note {{instantiation}}
414 }
415 
416 namespace qualified_friend_no_match {
417   void f(int); // expected-note {{type mismatch at 1st parameter}}
418   template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
419   struct X {
420     friend void qualified_friend_no_match::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}}
421     friend void qualified_friend_no_match::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}}
422   };
423 
424   struct Y {
425     void f(int); // expected-note {{type mismatch at 1st parameter}}
426     template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
427   };
428   struct Z {
429     friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}}
430   };
431 }
432