Clang Project

clang_source_code/test/CXX/class.access/class.friend/p1.cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
4// RUN: %clang_cc1 -fsyntax-only -verify %s
5
6// C++'0x [class.friend] p1:
7//   A friend of a class is a function or class that is given permission to use
8//   the private and protected member names from the class. A class specifies
9//   its friends, if any, by way of friend declarations. Such declarations give
10//   special access rights to the friends, but they do not make the nominated
11//   friends members of the befriending class.
12
13struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
14S* g() { return 0; } // expected-note 2 {{'g' declared here}}
15
16struct X {
17  friend struct S;
18  friend S* g();
19};
20
21void test1() {
22  S s;
23  g()->f();
24  S::f();
25  X::g(); // expected-error{{no member named 'g' in 'X'; did you mean simply 'g'?}}
26  X::S x_s; // expected-error{{no type named 'S' in 'X'; did you mean simply 'S'?}}
27  X x;
28  x.g(); // expected-error{{no member named 'g' in 'X'}}
29}
30
31// Test that we recurse through namespaces to find already declared names, but
32// new names are declared within the enclosing namespace.
33namespace N {
34  struct X {
35    friend struct S;
36    friend S* g();
37
38    friend struct S2;
39    friend struct S2* g2();
40  };
41
42  struct S2 { static void f2(); }; // expected-note 2 {{'S2' declared here}}
43  S2* g2() { return 0; } // expected-note 2 {{'g2' declared here}}
44
45  void test() {
46    g()->f();
47    S s;
48    S::f();
49    X::g(); // expected-error{{no member named 'g' in 'N::X'; did you mean simply 'g'?}}
50    X::S x_s; // expected-error{{no type named 'S' in 'N::X'; did you mean simply 'S'?}}
51    X x;
52    x.g(); // expected-error{{no member named 'g' in 'N::X'}}
53
54    g2();
55    S2 s2;
56    ::g2(); // expected-error{{no member named 'g2' in the global namespace; did you mean simply 'g2'?}}
57    ::S2 g_s2; // expected-error{{no type named 'S2' in the global namespace; did you mean simply 'S2'?}}
58    X::g2(); // expected-error{{no member named 'g2' in 'N::X'; did you mean simply 'g2'?}}
59    X::S2 x_s2; // expected-error{{no type named 'S2' in 'N::X'; did you mean simply 'S2'?}}
60    x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}
61  }
62}
63
64namespace test0 {
65  class ClassFriend {
66    void test();
67  };
68
69  class MemberFriend {
70  public:
71    void test();
72  };
73
74  void declared_test();
75
76  class Class {
77    static void member(); // expected-note 2 {{declared private here}}
78
79    friend class ClassFriend;
80    friend class UndeclaredClassFriend;
81
82    friend void undeclared_test();
83    friend void declared_test();
84    friend void MemberFriend::test();
85  };
86
87  void declared_test() {
88    Class::member();
89  }
90
91  void undeclared_test() {
92    Class::member();
93  }
94
95  void unfriended_test() {
96    Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}
97  }
98
99  void ClassFriend::test() {
100    Class::member();
101  }
102
103  void MemberFriend::test() {
104    Class::member();
105  }
106
107  class UndeclaredClassFriend {
108    void test() {
109      Class::member();
110    }
111  };
112
113  class ClassNonFriend {
114    void test() {
115      Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}
116    }
117  };
118}
119
120// Make sure that friends have access to inherited protected members.
121namespace test2 {
122  struct X;
123
124  class ilist_half_node {
125    friend struct ilist_walker_bad;
126    X *Prev;
127  protected:
128    X *getPrev() { return Prev; } // expected-note{{member is declared here}}
129  };
130
131  class ilist_node : private ilist_half_node { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
132    friend struct ilist_walker;
133    X *Next;
134    X *getNext() { return Next; } // expected-note {{declared private here}}
135  };
136
137  struct X : ilist_node {};
138
139  struct ilist_walker {
140    static X *getPrev(X *N) { return N->getPrev(); }
141    static X *getNext(X *N) { return N->getNext(); }
142  };  
143
144  struct ilist_walker_bad {
145    static X *getPrev(X *N) { return N->getPrev(); } // \
146    // expected-error {{'getPrev' is a private member of 'test2::ilist_half_node'}} \
147    // expected-error {{cannot cast 'test2::X' to its private base class 'test2::ilist_half_node'}}
148
149    static X *getNext(X *N) { return N->getNext(); } // \
150    // expected-error {{'getNext' is a private member of 'test2::ilist_node'}}
151  };  
152}
153
154namespace test3 {
155  class A { protected: int x; }; // expected-note {{declared protected here}}
156
157  class B : public A {
158    friend int foo(B*);
159  };
160
161  int foo(B *p) {
162    return p->x;
163  }
164
165  int foo(const B *p) {
166    return p->x; // expected-error {{'x' is a protected member of 'test3::A'}}
167  }
168}
169
170namespace test3a {
171  class A { protected: int x; };
172
173  class B : public A {
174    friend int foo(B*);
175  };
176
177  int foo(B * const p) {
178    return p->x;
179  }
180}
181
182namespace test4 {
183  template <class T> class Holder {
184    T object;
185    friend bool operator==(Holder &a, Holder &b) {
186      return a.object == b.object; // expected-error {{invalid operands to binary expression}}
187    }
188  };
189
190  struct Inequal {};
191  bool test() {
192    Holder<Inequal> a, b;
193    return a == b;  // expected-note {{requested here}}
194  }
195}
196
197
198// PR6174
199namespace test5 {
200  namespace ns {
201    class A;
202  }
203
204  class ns::A {
205  private: int x;
206    friend class B;
207  };
208
209  namespace ns {
210    class B {
211      int test(A *p) { return p->x; }
212    };
213  }
214}
215
216// PR6207
217namespace test6 {
218  struct A {};
219
220  struct B {
221    friend
222#if __cplusplus >= 201103L
223      constexpr
224#endif
225      A::A();
226    friend A::~A();
227    friend
228#if __cplusplus >= 201402L
229      constexpr
230#endif
231      A &A::operator=(const A&);
232  };
233}
234
235namespace test7 {
236  template <class T> struct X {
237    X();
238    ~X();
239    void foo();
240    void bar();
241  };
242
243  class A {
244    friend void X<int>::foo();
245    friend X<int>::X();
246    friend
247#if __cplusplus >= 201103L
248      constexpr
249#endif
250      X<int>::X(const X&);
251
252  private:
253    A(); // expected-note 2 {{declared private here}}
254  };
255
256  template<> void X<int>::foo() {
257    A a;
258  }
259
260  template<> void X<int>::bar() {
261    A a; // expected-error {{calling a private constructor}}
262  }
263
264  template<> X<int>::X() {
265    A a;
266  }
267
268  template<> X<int>::~X() {
269    A a; // expected-error {{calling a private constructor}}
270  }
271}
272
273// Return types, parameters and default arguments to friend functions.
274namespace test8 {
275  class A {
276    typedef int I; // expected-note 4 {{declared private here}}
277    static const I x = 0; // expected-note {{implicitly declared private here}}
278    friend I f(I i);
279    template<typename T> friend I g(I i);
280  };
281
282  const A::I A::x;
283  A::I f(A::I i = A::x) {}
284  template<typename T> A::I g(A::I i) {
285    T t;
286  }
287  template A::I g<A::I>(A::I i);
288
289  A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}}
290  template<typename T> A::I g2(A::I i) { // expected-error 2 {{is a private member of}}
291    T t;
292  }
293  template A::I g2<A::I>(A::I i);
294}
295
296// PR6885
297namespace test9 {
298  class B {
299    friend class test9;
300  };
301}
302
303// PR7230
304namespace test10 {
305  extern "C" void test10_f(void);
306  extern "C" void test10_g(void);
307
308  namespace NS {
309    class C {
310      void foo(void); // expected-note {{declared private here}}
311      friend void test10::test10_f(void);
312    };
313    static C* bar;
314  }
315
316  void test10_f(void) {
317    NS::bar->foo();
318  }
319
320  void test10_g(void) {
321    NS::bar->foo(); // expected-error {{private member}}
322  }
323}
324
325// PR8705
326namespace test11 {
327  class A {
328  public:
329    void test0(int);
330    void test1(int);
331    void test2(int);
332    void test3(int);
333  };
334
335  class B {
336    typedef int private_type; // expected-note 2 {{implicitly declared private here}}
337    friend void A::test0(int);
338    friend void A::test1(int);
339  };
340
341  void A::test0(B::private_type x) {}
342  void A::test1(int x = B::private_type()) {}
343  void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}}
344  void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}}
345}
346
347
348// PR9221
349namespace test12 {
350  struct A {
351    void foo();
352  };
353  class B : private A {
354    friend void A::foo();
355    void *mem;
356  };
357  void A::foo() {
358    void *var = static_cast<B*>(this)->mem;
359  }
360}
361
362namespace PR9103 {
363  struct base {
364  protected:
365    static void foo(void) {}
366  };
367
368  struct cls: base {
369    friend void bar(void) {
370      base::foo();
371    }
372  };
373}
374
375// PR13642.  When computing the effective context, we were walking up
376// the DC chain for the canonical decl, which is unfortunate if that's
377// (e.g.) a friend declaration.
378namespace test14 {
379  class A {
380    class B { // expected-note {{implicitly declared private here}}
381      static int i;
382      friend void c();
383    };
384  };
385
386  void c() {
387    A::B::i = 5; // expected-error {{'B' is a private member of 'test14::A'}}
388  }
389}
390