1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 2 3friend class A; // expected-error {{'friend' used outside of class}} 4void f() { friend class A; } // expected-error {{'friend' used outside of class}} 5class C { friend class A; }; 6class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}} 7 8// PR5760 9namespace 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 20namespace 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 34namespace 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 45namespace test3 { 46 class Foo { 47 friend const int getInt(int inInt = 0) {} 48 49 }; 50} 51 52namespace 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 66namespace rdar8529993 { 67struct A { ~A(); }; 68 69struct B : A 70{ 71 template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}} 72}; 73} 74 75// PR7915 76namespace test5 { 77 struct A; 78 struct A1 { friend void A(); }; 79 80 struct B { friend void B(); }; 81} 82 83// PR8479 84namespace 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} 99namespace 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} 115namespace 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 134namespace test7 { 135 extern "C" { 136 class X { 137 friend int test7_f() { return 42; } 138 }; 139 } 140} 141 142// PR15485 143namespace 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 {{target of using declaration}} 151 struct B : public A { using A::f; }; // expected-note {{using declaration}} 152 struct X { 153 template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} 154 friend void B::f(); // expected-error {{cannot befriend target of using declaration}} 155 }; 156} 157 158// PR16423 159namespace test9 { 160 class C { 161 }; 162 struct A { 163 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}} 164 }; 165} 166 167namespace test10 { 168 struct X {}; 169 extern void f10_a(); 170 extern void f10_a(X); 171 struct A { 172 friend void f10_a(); 173 friend void f10_b(); 174 friend void f10_c(); 175 friend void f10_d(); 176 friend void f10_a(X); 177 friend void f10_b(X); 178 friend void f10_c(X); 179 friend void f10_d(X); 180 }; 181 extern void f10_b(); 182 extern void f10_b(X); 183 struct B { 184 friend void f10_a(); 185 friend void f10_b(); 186 friend void f10_c(); 187 friend void f10_d(); 188 friend void f10_a(X); 189 friend void f10_b(X); 190 friend void f10_c(X); 191 friend void f10_d(X); 192 }; 193 extern void f10_c(); 194 extern void f10_c(X); 195 196 // FIXME: Give a better diagnostic for the case where a function exists but is 197 // not visible. 198 void g(X x) { 199 f10_a(); 200 f10_b(); 201 f10_c(); 202 f10_d(); // expected-error {{undeclared identifier}} 203 204 ::test10::f10_a(); 205 ::test10::f10_b(); 206 ::test10::f10_c(); 207 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} 208 209 f10_a(x); 210 f10_b(x); 211 f10_c(x); 212 f10_d(x); // PR16597: expected-error {{undeclared identifier}} 213 214 ::test10::f10_a(x); 215 ::test10::f10_b(x); 216 ::test10::f10_c(x); 217 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} 218 } 219 220 struct Y : X { 221 friend void f10_d(); 222 friend void f10_d(X); 223 }; 224 225 struct Z { 226 operator X(); 227 friend void f10_d(); 228 friend void f10_d(X); 229 }; 230 231 void g(X x, Y y, Z z) { 232 f10_d(); // expected-error {{undeclared identifier}} 233 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} 234 235 // f10_d is visible to ADL in the second and third cases. 236 f10_d(x); // expected-error {{undeclared identifier}} 237 f10_d(y); 238 f10_d(z); 239 240 // No ADL here. 241 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} 242 ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}} 243 ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}} 244 } 245 246 void local_externs(X x, Y y) { 247 extern void f10_d(); 248 extern void f10_d(X); 249 f10_d(); 250 f10_d(x); 251 // FIXME: This lookup should fail, because the local extern declaration 252 // should suppress ADL. 253 f10_d(y); 254 { 255 int f10_d; 256 f10_d(); // expected-error {{not a function}} 257 f10_d(x); // expected-error {{not a function}} 258 f10_d(y); // expected-error {{not a function}} 259 } 260 } 261 262 void i(X x, Y y) { 263 f10_d(); // expected-error {{undeclared identifier}} 264 f10_d(x); // expected-error {{undeclared identifier}} 265 f10_d(y); 266 } 267 268 struct C { 269 friend void f10_d(); 270 friend void f10_d(X); 271 }; 272 273 void j(X x, Y y) { 274 f10_d(); // expected-error {{undeclared identifier}} 275 f10_d(x); // expected-error {{undeclared identifier}} 276 f10_d(y); 277 } 278 279 extern void f10_d(); 280 extern void f10_d(X); 281 void k(X x, Y y, Z z) { 282 // All OK now. 283 f10_d(); 284 f10_d(x); 285 ::test10::f10_d(); 286 ::test10::f10_d(x); 287 ::test10::f10_d(y); 288 ::test10::f10_d(z); 289 } 290} 291 292namespace test11 { 293 class __attribute__((visibility("hidden"))) B; 294 295 class A { 296 friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}} 297 }; 298} 299 300namespace pr21851 { 301// PR21851 was a problem where we assumed that when the friend function redecl 302// lookup found a C++ method, it would necessarily have a qualifier. Below we 303// have some test cases where unqualified lookup finds C++ methods without using 304// qualifiers. Unfortunately, we can't exercise the case of an access check 305// failure because nested classes always have access to the members of outer 306// classes. 307 308void friend_own_method() { 309 class A { 310 void m() {} 311 friend void m(); 312 }; 313} 314 315void friend_enclosing_method() { 316 class A; 317 class C { 318 int p; 319 friend class A; 320 }; 321 class A { 322 void enclosing_friend() { 323 (void)b->p; 324 (void)c->p; 325 } 326 class B { 327 void b(A *a) { 328 (void)a->c->p; 329 } 330 int p; 331 friend void enclosing_friend(); 332 }; 333 B *b; 334 C *c; 335 }; 336} 337 338static auto friend_file_func() { 339 extern void file_scope_friend(); 340 class A { 341 int p; 342 friend void file_scope_friend(); 343 }; 344 return A(); 345} 346 347void file_scope_friend() { 348 auto a = friend_file_func(); 349 (void)a.p; 350} 351} 352 353template<typename T> 354struct X_pr6954 { 355 operator int(); 356 friend void f_pr6954(int x); 357}; 358 359int array0_pr6954[sizeof(X_pr6954<int>)]; 360int array1_pr6954[sizeof(X_pr6954<float>)]; 361 362void g_pr6954() { 363 f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} 364} 365 366