p1.cpp revision b5c7768a74936d4e2c7a484570a638cb74702d8b
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 10struct S { static void f(); }; // expected-note 2 {{'S' declared here}} 11S* g() { return 0; } // expected-note 2 {{'g' declared here}} 12 13struct X { 14 friend struct S; 15 friend S* g(); 16}; 17 18void test1() { 19 S s; 20 g()->f(); 21 S::f(); 22 X::g(); // expected-error{{no member named 'g' in 'X'; did you mean simply 'g'?}} 23 X::S x_s; // expected-error{{no type named 'S' in 'X'; did you mean simply 'S'?}} 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. 30namespace 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(); }; // expected-note 2 {{'S2' declared here}} 40 S2* g2() { return 0; } // expected-note 2 {{'g2' declared here}} 41 42 void test() { 43 g()->f(); 44 S s; 45 S::f(); 46 X::g(); // expected-error{{no member named 'g' in 'N::X'; did you mean simply 'g'?}} 47 X::S x_s; // expected-error{{no type named 'S' in 'N::X'; did you mean simply 'S'?}} 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; did you mean simply 'g2'?}} 54 ::S2 g_s2; // expected-error{{no type named 'S2' in the global namespace; did you mean simply 'S2'?}} 55 X::g2(); // expected-error{{no member named 'g2' in 'N::X'; did you mean simply 'g2'?}} 56 X::S2 x_s2; // expected-error{{no type named 'S2' in 'N::X'; did you mean simply 'S2'?}} 57 x.g2(); // expected-error{{no member named 'g2' in 'N::X'}} 58 } 59} 60 61namespace 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 84 void declared_test() { 85 Class::member(); 86 } 87 88 void undeclared_test() { 89 Class::member(); 90 } 91 92 void unfriended_test() { 93 Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} 94 } 95 96 void ClassFriend::test() { 97 Class::member(); 98 } 99 100 void MemberFriend::test() { 101 Class::member(); 102 } 103 104 class UndeclaredClassFriend { 105 void test() { 106 Class::member(); 107 } 108 }; 109 110 class ClassNonFriend { 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. 118namespace test2 { 119 struct X; 120 121 class ilist_half_node { 122 friend struct ilist_walker_bad; 123 X *Prev; 124 protected: 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; 131 X *getNext() { return Next; } // expected-note {{declared private here}} 132 }; 133 134 struct X : ilist_node {}; 135 136 struct ilist_walker { 137 static X *getPrev(X *N) { return N->getPrev(); } 138 static X *getNext(X *N) { return N->getNext(); } 139 }; 140 141 struct ilist_walker_bad { 142 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 146 static X *getNext(X *N) { return N->getNext(); } // \ 147 // expected-error {{'getNext' is a private member of 'test2::ilist_node'}} 148 }; 149} 150 151namespace 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 158 int foo(B *p) { 159 return p->x; 160 } 161 162 int foo(const B *p) { 163 return p->x; // expected-error {{'x' is a protected member of 'test3::A'}} 164 } 165} 166 167namespace test3a { 168 class A { protected: int x; }; 169 170 class B : public A { 171 friend int foo(B*); 172 }; 173 174 int foo(B * const p) { 175 return p->x; 176 } 177} 178 179namespace test4 { 180 template <class T> class Holder { 181 T object; 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 {}; 188 bool test() { 189 Holder<Inequal> a, b; 190 return a == b; // expected-note {{requested here}} 191 } 192} 193 194 195// PR6174 196namespace 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 { 208 int test(A *p) { return p->x; } 209 }; 210 } 211} 212 213// PR6207 214namespace 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 224namespace 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 241 template<> void X<int>::foo() { 242 A a; 243 } 244 245 template<> void X<int>::bar() { 246 A a; // expected-error {{calling a private constructor}} 247 } 248 249 template<> X<int>::X() { 250 A a; 251 } 252 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. 259namespace 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; 268 A::I f(A::I i = A::x) {} 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 274 A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}} 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 282namespace test9 { 283 class B { 284 friend class test9; 285 }; 286} 287 288// PR7230 289namespace test10 { 290 extern "C" void test10_f(void); 291 extern "C" void test10_g(void); 292 293 namespace NS { 294 class C { 295 void foo(void); // expected-note {{declared private here}} 296 friend void test10::test10_f(void); 297 }; 298 static C* bar; 299 } 300 301 void test10_f(void) { 302 NS::bar->foo(); 303 } 304 305 void test10_g(void) { 306 NS::bar->foo(); // expected-error {{private member}} 307 } 308} 309 310// PR8705 311namespace 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 326 void A::test0(B::private_type x) {} 327 void A::test1(int x = B::private_type()) {} 328 void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}} 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 334namespace test12 { 335 struct A { 336 void foo(); 337 }; 338 class B : private A { 339 friend void A::foo(); 340 void *mem; 341 }; 342 void A::foo() { 343 void *var = static_cast<B*>(this)->mem; 344 } 345} 346 347namespace PR9103 { 348 struct base { 349 protected: 350 static void foo(void) {} 351 }; 352 353 struct cls: base { 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. 363namespace test14 { 364 class A { 365 class B { // expected-note {{implicitly declared private here}} 366 static int i; 367 friend void c(); 368 }; 369 }; 370 371 void c() { 372 A::B::i = 5; // expected-error {{'B' is a private member of 'test14::A'}} 373 } 374} 375