Home | History | Annotate | Download | only in SemaCXX
      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