432 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++142 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// PR57609namespace 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.h20namespace 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// PR547634namespace 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// PR513445namespace 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 here61 };62 63 class T4B {};64}65 66namespace rdar8529993 {67struct A { ~A(); };68 69struct B : A70{71 template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}}72};73}74 75// PR791576namespace test5 {77 struct A;78 struct A1 { friend void A(); };79 80 struct B { friend void B(); };81}82 83// PR847984namespace 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// PR15485143namespace 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// PR16423161namespace test9 {162 class C {163 };164 struct A {165 friend void C::f(int, int, int) {} // expected-error {{friend declaration of 'f' does not match any declaration in 'test9::C'}}166 };167}168 169namespace 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 is199 // 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 struct W {234 friend void f10_d(W);235 };236 237 void g(X x, Y y, Z z) {238 f10_d(); // expected-error {{undeclared identifier}}239 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}240 241 // f10_d is visible to ADL in the second and third cases.242 f10_d(x); // expected-error {{undeclared identifier}}243 f10_d(y);244 f10_d(z);245 246 // No ADL here.247 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}248 ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}249 ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}250 }251 252 void local_externs(W w, X x, Y y) {253 extern void f10_d(); // expected-note {{candidate}}254 extern void f10_d(X); // expected-note {{candidate}}255 f10_d();256 f10_d(x);257 f10_d(y);258 f10_d(w); // expected-error {{no matching}}259 {260 int f10_d;261 f10_d(); // expected-error {{not a function}}262 f10_d(x); // expected-error {{not a function}}263 f10_d(y); // expected-error {{not a function}}264 }265 }266 267 void i(X x, Y y) {268 f10_d(); // expected-error {{undeclared identifier}}269 f10_d(x); // expected-error {{undeclared identifier}}270 f10_d(y);271 }272 273 struct C {274 friend void f10_d();275 friend void f10_d(X);276 };277 278 void j(X x, Y y) {279 f10_d(); // expected-error {{undeclared identifier}}280 f10_d(x); // expected-error {{undeclared identifier}}281 f10_d(y);282 }283 284 extern void f10_d();285 extern void f10_d(X);286 void k(X x, Y y, Z z) {287 // All OK now.288 f10_d();289 f10_d(x);290 ::test10::f10_d();291 ::test10::f10_d(x);292 ::test10::f10_d(y);293 ::test10::f10_d(z);294 }295}296 297namespace test11 {298 class __attribute__((visibility("hidden"))) B;299 300 class A {301 friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}302 };303}304 305namespace pr21851 {306// PR21851 was a problem where we assumed that when the friend function redecl307// lookup found a C++ method, it would necessarily have a qualifier. Below we308// have some test cases where unqualified lookup finds C++ methods without using309// qualifiers. Unfortunately, we can't exercise the case of an access check310// failure because nested classes always have access to the members of outer311// classes.312 313void friend_own_method() {314 class A {315 void m() {}316 friend void m();317 };318}319 320void friend_enclosing_method() {321 class A;322 class C {323 int p;324 friend class A;325 };326 class A {327 void enclosing_friend() {328 (void)b->p;329 (void)c->p;330 }331 class B {332 void b(A *a) {333 (void)a->c->p;334 }335 int p;336 friend void enclosing_friend();337 };338 B *b;339 C *c;340 };341}342 343static auto friend_file_func() {344 extern void file_scope_friend();345 class A {346 int p;347 friend void file_scope_friend();348 };349 return A();350}351 352void file_scope_friend() {353 auto a = friend_file_func();354 (void)a.p;355}356}357 358template<typename T>359struct X_pr6954 {360 operator int();361 friend void f_pr6954(int x);362};363 364int array0_pr6954[sizeof(X_pr6954<int>)];365int array1_pr6954[sizeof(X_pr6954<float>)];366 367void g_pr6954() {368 f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}369}370 371namespace tag_redecl {372 namespace N {373 struct X *p;374 namespace {375 class K {376 friend struct X;377 };378 }379 }380 namespace N {381 struct X;382 X *q = p;383 }384}385 386namespace default_arg {387 void f();388 void f(void*); // expected-note {{previous}}389 struct X {390 friend void f(int a, int b = 0) {}391 friend void f(void *p = 0) {} // expected-error {{must be the only}}392 };393}394 395namespace PR33222 {396 int f();397 template<typename T> struct X {398 friend T f();399 };400 X<int> xi;401 402 int g(); // expected-note {{previous}}403 template<typename T> struct Y {404 friend T g(); // expected-error {{return type}}405 };406 Y<float> yf; // expected-note {{instantiation}}407 408 int h(); // expected-note {{previous}}409 template<typename T> struct Z {410 friend T h(); // expected-error {{return type}}411 };412 Z<int> zi;413 Z<float> zf; // expected-note {{instantiation}}414}415 416namespace qualified_friend_no_match {417 void f(int); // expected-note {{type mismatch at 1st parameter}}418 template<typename T> void f(T*); // expected-note {{could not match 'T *' against 'double'}}419 struct X {420 friend void qualified_friend_no_match::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}}421 friend void qualified_friend_no_match::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}}422 };423 424 struct Y {425 void f(int); // expected-note {{type mismatch at 1st parameter}}426 template<typename T> void f(T*); // expected-note {{could not match 'T *' against 'double'}}427 };428 struct Z {429 friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}}430 };431}432