1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
2
3friend class A; // expected-error {{'friend' used outside of class}}
4void f() { friend class A; } // expected-error {{'friend' used outside of class}}
5class C { friend class A; };
6class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}}
7
8// PR5760
9namespace 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
20namespace test1 {
21  template <class T> struct Outer {
22    void foo(T);
23    struct Inner {
24      friend void Outer::foo(T);
25    };
26  };
27
28  void test() {
29    (void) Outer<int>::Inner();
30  }
31}
32
33// PR5476
34namespace 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
45namespace test3 {
46  class Foo {
47    friend const int getInt(int inInt = 0) {}
48
49  };
50}
51
52namespace 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
66namespace rdar8529993 {
67struct A { ~A(); };
68
69struct B : A
70{
71  template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}}
72};
73}
74
75// PR7915
76namespace test5 {
77  struct A;
78  struct A1 { friend void A(); };
79
80  struct B { friend void B(); };
81}
82
83// PR8479
84namespace test6_1 {
85  class A {
86   public:
87   private:
88    friend class vectorA;
89    A() {}
90  };
91  class vectorA {
92   public:
93    vectorA(int i, const A& t = A()) {}
94  };
95  void f() {
96    vectorA v(1);
97  }
98}
99namespace test6_2 {
100  template<class T>
101  class vector {
102   public:
103    vector(int i, const T& t = T()) {}
104  };
105  class A {
106   public:
107   private:
108    friend class vector<A>;
109    A() {}
110  };
111  void f() {
112    vector<A> v(1);
113  }
114}
115namespace test6_3 {
116  template<class T>
117  class vector {
118   public:
119    vector(int i) {}
120    void f(const T& t = T()) {}
121  };
122  class A {
123   public:
124   private:
125    friend void vector<A>::f(const A&);
126    A() {}
127  };
128  void f() {
129    vector<A> v(1);
130    v.f();
131  }
132}
133
134namespace test7 {
135  extern "C" {
136    class X {
137      friend int test7_f() { return 42; }
138    };
139  }
140}
141
142// PR15485
143namespace 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
161namespace test9 {
162  class C {
163  };
164  struct A {
165    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  };
167}
168
169namespace 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.
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  void g(X x, Y y, Z z) {
234    f10_d(); // expected-error {{undeclared identifier}}
235    ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
236
237    // f10_d is visible to ADL in the second and third cases.
238    f10_d(x); // expected-error {{undeclared identifier}}
239    f10_d(y);
240    f10_d(z);
241
242    // No ADL here.
243    ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
244    ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
245    ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
246  }
247
248  void local_externs(X x, Y y) {
249    extern void f10_d();
250    extern void f10_d(X);
251    f10_d();
252    f10_d(x);
253    // FIXME: This lookup should fail, because the local extern declaration
254    // should suppress ADL.
255    f10_d(y);
256    {
257      int f10_d;
258      f10_d(); // expected-error {{not a function}}
259      f10_d(x); // expected-error {{not a function}}
260      f10_d(y); // expected-error {{not a function}}
261    }
262  }
263
264  void i(X x, Y y) {
265    f10_d(); // expected-error {{undeclared identifier}}
266    f10_d(x); // expected-error {{undeclared identifier}}
267    f10_d(y);
268  }
269
270  struct C {
271    friend void f10_d();
272    friend void f10_d(X);
273  };
274
275  void j(X x, Y y) {
276    f10_d(); // expected-error {{undeclared identifier}}
277    f10_d(x); // expected-error {{undeclared identifier}}
278    f10_d(y);
279  }
280
281  extern void f10_d();
282  extern void f10_d(X);
283  void k(X x, Y y, Z z) {
284    // All OK now.
285    f10_d();
286    f10_d(x);
287    ::test10::f10_d();
288    ::test10::f10_d(x);
289    ::test10::f10_d(y);
290    ::test10::f10_d(z);
291  }
292}
293
294namespace test11 {
295  class __attribute__((visibility("hidden"))) B;
296
297  class A {
298    friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
299  };
300}
301
302namespace pr21851 {
303// PR21851 was a problem where we assumed that when the friend function redecl
304// lookup found a C++ method, it would necessarily have a qualifier. Below we
305// have some test cases where unqualified lookup finds C++ methods without using
306// qualifiers. Unfortunately, we can't exercise the case of an access check
307// failure because nested classes always have access to the members of outer
308// classes.
309
310void friend_own_method() {
311  class A {
312    void m() {}
313    friend void m();
314  };
315}
316
317void friend_enclosing_method() {
318  class A;
319  class C {
320    int p;
321    friend class A;
322  };
323  class A {
324    void enclosing_friend() {
325      (void)b->p;
326      (void)c->p;
327    }
328    class B {
329      void b(A *a) {
330        (void)a->c->p;
331      }
332      int p;
333      friend void enclosing_friend();
334    };
335    B *b;
336    C *c;
337  };
338}
339
340static auto friend_file_func() {
341  extern void file_scope_friend();
342  class A {
343    int p;
344    friend void file_scope_friend();
345  };
346  return A();
347}
348
349void file_scope_friend() {
350  auto a = friend_file_func();
351  (void)a.p;
352}
353}
354
355template<typename T>
356struct X_pr6954 {
357  operator int();
358  friend void f_pr6954(int x);
359};
360
361int array0_pr6954[sizeof(X_pr6954<int>)];
362int array1_pr6954[sizeof(X_pr6954<float>)];
363
364void g_pr6954() {
365  f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
366}
367
368namespace tag_redecl {
369  namespace N {
370    struct X *p;
371    namespace {
372      class K {
373        friend struct X;
374      };
375    }
376  }
377  namespace N {
378    struct X;
379    X *q = p;
380  }
381}
382