1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 2 3 friend class A; // expected-error {{'friend' used outside of class}} 4 void f() { friend class A; } // expected-error {{'friend' used outside of class}} 5 class C { friend class A; }; 6 class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}} 7 8 // PR5760 9 namespace test0 { 10 namespace ns { 11 void f(int); 12 } 13 14 struct A { 15 friend void ns::f(int a); 16 }; 17 } 18 19 // Test derived from LLVM's Registry.h 20 namespace test1 { 21 template <class T> struct Outer { 22 void foo(T); 23 struct Inner { 24 friend void Outer::foo(T); 25 }; 26 }; 27 28 void test() { 29 (void) Outer<int>::Inner(); 30 } 31 } 32 33 // PR5476 34 namespace test2 { 35 namespace foo { 36 void Func(int x); 37 } 38 39 class Bar { 40 friend void ::test2::foo::Func(int x); 41 }; 42 } 43 44 // PR5134 45 namespace test3 { 46 class Foo { 47 friend const int getInt(int inInt = 0) {} 48 49 }; 50 } 51 52 namespace test4 { 53 class T4A { 54 friend class T4B; 55 56 public: 57 T4A(class T4B *); 58 59 protected: 60 T4B *mB; // error here 61 }; 62 63 class T4B {}; 64 } 65 66 namespace rdar8529993 { 67 struct A { ~A(); }; 68 69 struct B : A 70 { 71 template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}} 72 }; 73 } 74 75 // PR7915 76 namespace test5 { 77 struct A; 78 struct A1 { friend void A(); }; 79 80 struct B { friend void B(); }; 81 } 82 83 // PR8479 84 namespace test6_1 { 85 class A { 86 public: 87 private: 88 friend class vectorA; 89 A() {} 90 }; 91 class vectorA { 92 public: 93 vectorA(int i, const A& t = A()) {} 94 }; 95 void f() { 96 vectorA v(1); 97 } 98 } 99 namespace test6_2 { 100 template<class T> 101 class vector { 102 public: 103 vector(int i, const T& t = T()) {} 104 }; 105 class A { 106 public: 107 private: 108 friend class vector<A>; 109 A() {} 110 }; 111 void f() { 112 vector<A> v(1); 113 } 114 } 115 namespace test6_3 { 116 template<class T> 117 class vector { 118 public: 119 vector(int i) {} 120 void f(const T& t = T()) {} 121 }; 122 class A { 123 public: 124 private: 125 friend void vector<A>::f(const A&); 126 A() {} 127 }; 128 void f() { 129 vector<A> v(1); 130 v.f(); 131 } 132 } 133 134 namespace test7 { 135 extern "C" { 136 class X { 137 friend int test7_f() { return 42; } 138 }; 139 } 140 } 141 142 // PR15485 143 namespace test8 { 144 namespace ns1 { 145 namespace ns2 { 146 template<class T> void f(T t); // expected-note {{target of using declaration}} 147 } 148 using ns2::f; // expected-note {{using declaration}} 149 } 150 struct A { void f(); }; // expected-note 2{{target of using declaration}} 151 struct B : public A { using A::f; }; // expected-note {{using declaration}} 152 template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}} 153 struct X { 154 template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} 155 friend void B::f(); // expected-error {{cannot befriend target of using declaration}} 156 friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}} 157 }; 158 } 159 160 // PR16423 161 namespace test9 { 162 class C { 163 }; 164 struct A { 165 friend void C::f(int, int, int) {} // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}} 166 }; 167 } 168 169 namespace test10 { 170 struct X {}; 171 extern void f10_a(); 172 extern void f10_a(X); 173 struct A { 174 friend void f10_a(); 175 friend void f10_b(); 176 friend void f10_c(); 177 friend void f10_d(); 178 friend void f10_a(X); 179 friend void f10_b(X); 180 friend void f10_c(X); 181 friend void f10_d(X); 182 }; 183 extern void f10_b(); 184 extern void f10_b(X); 185 struct B { 186 friend void f10_a(); 187 friend void f10_b(); 188 friend void f10_c(); 189 friend void f10_d(); 190 friend void f10_a(X); 191 friend void f10_b(X); 192 friend void f10_c(X); 193 friend void f10_d(X); 194 }; 195 extern void f10_c(); 196 extern void f10_c(X); 197 198 // FIXME: Give a better diagnostic for the case where a function exists but is 199 // not visible. 200 void g(X x) { 201 f10_a(); 202 f10_b(); 203 f10_c(); 204 f10_d(); // expected-error {{undeclared identifier}} 205 206 ::test10::f10_a(); 207 ::test10::f10_b(); 208 ::test10::f10_c(); 209 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} 210 211 f10_a(x); 212 f10_b(x); 213 f10_c(x); 214 f10_d(x); // PR16597: expected-error {{undeclared identifier}} 215 216 ::test10::f10_a(x); 217 ::test10::f10_b(x); 218 ::test10::f10_c(x); 219 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} 220 } 221 222 struct Y : X { 223 friend void f10_d(); 224 friend void f10_d(X); 225 }; 226 227 struct Z { 228 operator X(); 229 friend void f10_d(); 230 friend void f10_d(X); 231 }; 232 233 void g(X x, Y y, Z z) { 234 f10_d(); // expected-error {{undeclared identifier}} 235 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} 236 237 // f10_d is visible to ADL in the second and third cases. 238 f10_d(x); // expected-error {{undeclared identifier}} 239 f10_d(y); 240 f10_d(z); 241 242 // No ADL here. 243 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} 244 ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}} 245 ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}} 246 } 247 248 void local_externs(X x, Y y) { 249 extern void f10_d(); 250 extern void f10_d(X); 251 f10_d(); 252 f10_d(x); 253 // FIXME: This lookup should fail, because the local extern declaration 254 // should suppress ADL. 255 f10_d(y); 256 { 257 int f10_d; 258 f10_d(); // expected-error {{not a function}} 259 f10_d(x); // expected-error {{not a function}} 260 f10_d(y); // expected-error {{not a function}} 261 } 262 } 263 264 void i(X x, Y y) { 265 f10_d(); // expected-error {{undeclared identifier}} 266 f10_d(x); // expected-error {{undeclared identifier}} 267 f10_d(y); 268 } 269 270 struct C { 271 friend void f10_d(); 272 friend void f10_d(X); 273 }; 274 275 void j(X x, Y y) { 276 f10_d(); // expected-error {{undeclared identifier}} 277 f10_d(x); // expected-error {{undeclared identifier}} 278 f10_d(y); 279 } 280 281 extern void f10_d(); 282 extern void f10_d(X); 283 void k(X x, Y y, Z z) { 284 // All OK now. 285 f10_d(); 286 f10_d(x); 287 ::test10::f10_d(); 288 ::test10::f10_d(x); 289 ::test10::f10_d(y); 290 ::test10::f10_d(z); 291 } 292 } 293 294 namespace test11 { 295 class __attribute__((visibility("hidden"))) B; 296 297 class A { 298 friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}} 299 }; 300 } 301 302 namespace pr21851 { 303 // PR21851 was a problem where we assumed that when the friend function redecl 304 // lookup found a C++ method, it would necessarily have a qualifier. Below we 305 // have some test cases where unqualified lookup finds C++ methods without using 306 // qualifiers. Unfortunately, we can't exercise the case of an access check 307 // failure because nested classes always have access to the members of outer 308 // classes. 309 310 void friend_own_method() { 311 class A { 312 void m() {} 313 friend void m(); 314 }; 315 } 316 317 void friend_enclosing_method() { 318 class A; 319 class C { 320 int p; 321 friend class A; 322 }; 323 class A { 324 void enclosing_friend() { 325 (void)b->p; 326 (void)c->p; 327 } 328 class B { 329 void b(A *a) { 330 (void)a->c->p; 331 } 332 int p; 333 friend void enclosing_friend(); 334 }; 335 B *b; 336 C *c; 337 }; 338 } 339 340 static auto friend_file_func() { 341 extern void file_scope_friend(); 342 class A { 343 int p; 344 friend void file_scope_friend(); 345 }; 346 return A(); 347 } 348 349 void file_scope_friend() { 350 auto a = friend_file_func(); 351 (void)a.p; 352 } 353 } 354 355 template<typename T> 356 struct X_pr6954 { 357 operator int(); 358 friend void f_pr6954(int x); 359 }; 360 361 int array0_pr6954[sizeof(X_pr6954<int>)]; 362 int array1_pr6954[sizeof(X_pr6954<float>)]; 363 364 void g_pr6954() { 365 f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} 366 } 367 368 namespace tag_redecl { 369 namespace N { 370 struct X *p; 371 namespace { 372 class K { 373 friend struct X; 374 }; 375 } 376 } 377 namespace N { 378 struct X; 379 X *q = p; 380 } 381 } 382