brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 4b18036 Raw
410 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s4// RUN: %clang_cc1 -fsyntax-only -verify %s5 6// C++'0x [class.friend] p1:7//   A friend of a class is a function or class that is given permission to use8//   the private and protected member names from the class. A class specifies9//   its friends, if any, by way of friend declarations. Such declarations give10//   special access rights to the friends, but they do not make the nominated11//   friends members of the befriending class.12 13struct S { static void f(); }; // expected-note 2 {{'S' declared here}}14S* g() { return 0; } // expected-note 2 {{'g' declared here}}15 16struct X {17  friend struct S;18  friend S* g();19};20 21void test1() {22  S s;23  g()->f();24  S::f();25  X::g(); // expected-error{{no member named 'g' in 'X'; did you mean simply 'g'?}}26  X::S x_s; // expected-error{{no type named 'S' in 'X'; did you mean simply 'S'?}}27  X x;28  x.g(); // expected-error{{no member named 'g' in 'X'}}29}30 31// Test that we recurse through namespaces to find already declared names, but32// new names are declared within the enclosing namespace.33namespace N {34  struct X {35    friend struct S;36    friend S* g();37 38    friend struct S2;39    friend struct S2* g2();40  };41 42  struct S2 { static void f2(); }; // expected-note 2 {{'S2' declared here}}43  S2* g2() { return 0; } // expected-note 2 {{'g2' declared here}}44 45  void test() {46    g()->f();47    S s;48    S::f();49    X::g(); // expected-error{{no member named 'g' in 'N::X'; did you mean simply 'g'?}}50    X::S x_s; // expected-error{{no type named 'S' in 'N::X'; did you mean simply 'S'?}}51    X x;52    x.g(); // expected-error{{no member named 'g' in 'N::X'}}53 54    g2();55    S2 s2;56    ::g2(); // expected-error{{no member named 'g2' in the global namespace; did you mean simply 'g2'?}}57    ::S2 g_s2; // expected-error{{no type named 'S2' in the global namespace; did you mean simply 'S2'?}}58    X::g2(); // expected-error{{no member named 'g2' in 'N::X'; did you mean simply 'g2'?}}59    X::S2 x_s2; // expected-error{{no type named 'S2' in 'N::X'; did you mean simply 'S2'?}}60    x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}61  }62}63 64namespace test0 {65  class ClassFriend {66    void test();67  };68 69  class MemberFriend {70  public:71    void test();72  };73 74  void declared_test();75 76  class Class {77    static void member(); // expected-note 2 {{declared private here}}78 79    friend class ClassFriend;80    friend class UndeclaredClassFriend;81 82    friend void undeclared_test();83    friend void declared_test();84    friend void MemberFriend::test();85  };86 87  void declared_test() {88    Class::member();89  }90 91  void undeclared_test() {92    Class::member();93  }94 95  void unfriended_test() {96    Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}97  }98 99  void ClassFriend::test() {100    Class::member();101  }102 103  void MemberFriend::test() {104    Class::member();105  }106 107  class UndeclaredClassFriend {108    void test() {109      Class::member();110    }111  };112 113  class ClassNonFriend {114    void test() {115      Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}}116    }117  };118}119 120// Make sure that friends have access to inherited protected members.121namespace test2 {122  struct X;123 124  class ilist_half_node {125    friend struct ilist_walker_bad;126    X *Prev;127  protected:128    X *getPrev() { return Prev; } // expected-note{{member is declared here}}129  };130 131  class ilist_node : private ilist_half_node { // expected-note {{constrained by private inheritance here}}132    friend struct ilist_walker;133    X *Next;134    X *getNext() { return Next; } // expected-note {{declared private here}}135  };136 137  struct X : ilist_node {};138 139  struct ilist_walker {140    static X *getPrev(X *N) { return N->getPrev(); }141    static X *getNext(X *N) { return N->getNext(); }142  };  143 144  struct ilist_walker_bad {145    static X *getPrev(X *N) { return N->getPrev(); } // \146    // expected-error {{'getPrev' is a private member of 'test2::ilist_half_node'}}147 148    static X *getNext(X *N) { return N->getNext(); } // \149    // expected-error {{'getNext' is a private member of 'test2::ilist_node'}}150  };  151}152 153namespace test3 {154  class A { protected: int x; }; // expected-note {{declared protected here}}155 156  class B : public A {157    friend int foo(B*);158  };159 160  int foo(B *p) {161    return p->x;162  }163 164  int foo(const B *p) {165    return p->x; // expected-error {{'x' is a protected member of 'test3::A'}}166  }167}168 169namespace test3a {170  class A { protected: int x; };171 172  class B : public A {173    friend int foo(B*);174  };175 176  int foo(B * const p) {177    return p->x;178  }179}180 181namespace test4 {182  template <class T> class Holder {183    T object;184    friend bool operator==(Holder &a, Holder &b) {185      return a.object == b.object; // expected-error {{invalid operands to binary expression}}186    }187  };188 189  struct Inequal {};190  bool test() {191    Holder<Inequal> a, b;192    return a == b;  // expected-note {{requested here}}193  }194}195 196 197// PR6174198namespace test5 {199  namespace ns {200    class A;201  }202 203  class ns::A {204  private: int x;205    friend class B;206  };207 208  namespace ns {209    class B {210      int test(A *p) { return p->x; }211    };212  }213}214 215// PR6207216namespace test6 {217  struct A {};218 219  struct B {220    friend221#if __cplusplus >= 201103L222      constexpr223#endif224      A::A()225#if __cplusplus >= 201703L226      noexcept227#endif228      ;229    friend A::~A();230    friend231#if __cplusplus >= 201402L232      constexpr233#endif234      A &A::operator=(const A&)235#if __cplusplus >= 201703L236      noexcept237#endif238      ;239  };240}241 242namespace test7 {243  template <class T> struct X {244    X();245    ~X();246    void foo();247    void bar();248  };249 250  class A {251    friend void X<int>::foo();252    friend X<int>::X();253    friend254#if __cplusplus >= 201103L255      constexpr256#endif257      X<int>::X(const X&)258#if __cplusplus >= 201703L259      noexcept260#endif261      ;262 263  private:264    A(); // expected-note 2 {{declared private here}}265  };266 267  template<> void X<int>::foo() {268    A a;269  }270 271  template<> void X<int>::bar() {272    A a; // expected-error {{calling a private constructor}}273  }274 275  template<> X<int>::X() {276    A a;277  }278 279  template<> X<int>::~X() {280    A a; // expected-error {{calling a private constructor}}281  }282}283 284// Return types, parameters and default arguments to friend functions.285namespace test8 {286  class A {287    typedef int I;        // expected-note 6 {{declared private here}}288    static const I x = 0; // expected-note {{implicitly declared private here}}289    friend I f(I i);290    template<typename T> friend I g(I i);291  };292 293  const A::I A::x;294  A::I f(A::I i = A::x) {}295  template<typename T> A::I g(A::I i) {296    T t;297  }298  template A::I g<A::I>(A::I i);299 300  A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}}301  template<typename T> A::I g2(A::I i) { // expected-error 2 {{is a private member of}}302    T t;303  }304  template <> A::I g2<char>(A::I i) { return 0; } // OK305  template A::I g2<A::I>(A::I i);                 // OK306  template <> A::I g2<char>(A::I i);              // OK307  template <> A::I g2<A::I *>(A::I i);            // OK308  template A::I g2<unsigned>(A::I i);             // OK309  template int g2<A::I **>(int i);                // OK310  template A::I g2<A::I ***>(A::I i);             // OK311 312  template <typename T> A::I g3(A::I i) { return 0; } // expected-error 2 {{is a private member of}}313  template <> int g3<A::I>(int i);                    // OK314}315 316// PR6885317namespace test9 {318  class B {319    friend class test9;320  };321}322 323// PR7230324namespace test10 {325  extern "C" void test10_f(void);326  extern "C" void test10_g(void);327 328  namespace NS {329    class C {330      void foo(void); // expected-note {{declared private here}}331      friend void test10::test10_f(void);332    };333    static C* bar;334  }335 336  void test10_f(void) {337    NS::bar->foo();338  }339 340  void test10_g(void) {341    NS::bar->foo(); // expected-error {{private member}}342  }343}344 345// PR8705346namespace test11 {347  class A {348  public:349    void test0(int);350    void test1(int);351    void test2(int);352    void test3(int);353  };354 355  class B {356    typedef int private_type; // expected-note 2 {{implicitly declared private here}}357    friend void A::test0(int);358    friend void A::test1(int);359  };360 361  void A::test0(B::private_type x) {}362  void A::test1(int x = B::private_type()) {}363  void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}}364  void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}}365}366 367 368// PR9221369namespace test12 {370  struct A {371    void foo();372  };373  class B : private A {374    friend void A::foo();375    void *mem;376  };377  void A::foo() {378    void *var = static_cast<B*>(this)->mem;379  }380}381 382namespace PR9103 {383  struct base {384  protected:385    static void foo(void) {}386  };387 388  struct cls: base {389    friend void bar(void) {390      base::foo();391    }392  };393}394 395// PR13642.  When computing the effective context, we were walking up396// the DC chain for the canonical decl, which is unfortunate if that's397// (e.g.) a friend declaration.398namespace test14 {399  class A {400    class B { // expected-note {{implicitly declared private here}}401      static int i;402      friend void c();403    };404  };405 406  void c() {407    A::B::i = 5; // expected-error {{'B' is a private member of 'test14::A'}}408  }409}410