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