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