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