Home | History | Annotate | Download | only in class.access
      1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
      2 
      3 // C++0x [class.access]p4:
      4 
      5 //   Access control is applied uniformly to all names, whether the
      6 //   names are referred to from declarations or expressions.  In the
      7 //   case of overloaded function names, access control is applied to
      8 //   the function selected by overload resolution.
      9 
     10 class Public {} PublicInst;
     11 class Protected {} ProtectedInst;
     12 class Private {} PrivateInst;
     13 
     14 namespace test0 {
     15   class A {
     16   public:
     17     void foo(Public&);
     18   protected:
     19     void foo(Protected&); // expected-note 2 {{declared protected here}}
     20   private:
     21     void foo(Private&); // expected-note 2 {{declared private here}}
     22   };
     23 
     24   void test(A *op) {
     25     op->foo(PublicInst);
     26     op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
     27     op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
     28 
     29     void (A::*a)(Public&) = &A::foo;
     30     void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}}
     31     void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}}
     32   }
     33 }
     34 
     35 // Member operators.
     36 namespace test1 {
     37   class A {
     38   public:
     39     void operator+(Public&);
     40     void operator[](Public&);
     41     void operator()(Public&);
     42     typedef void (*PublicSurrogate)(Public&);
     43     operator PublicSurrogate() const;
     44   protected:
     45     void operator+(Protected&); // expected-note {{declared protected here}}
     46     void operator[](Protected&); // expected-note {{declared protected here}}
     47     void operator()(Protected&); // expected-note {{declared protected here}}
     48     typedef void (*ProtectedSurrogate)(Protected&);
     49     operator ProtectedSurrogate() const; // expected-note {{declared protected here}}
     50   private:
     51     void operator+(Private&); // expected-note {{declared private here}}
     52     void operator[](Private&); // expected-note {{declared private here}}
     53     void operator()(Private&); // expected-note {{declared private here}}
     54     void operator-(); // expected-note {{declared private here}}
     55     typedef void (*PrivateSurrogate)(Private&);
     56     operator PrivateSurrogate() const; // expected-note {{declared private here}}
     57   };
     58   void operator+(const A &, Public&);
     59   void operator+(const A &, Protected&);
     60   void operator+(const A &, Private&);
     61   void operator-(const A &);
     62 
     63   void test(A &a, Public &pub, Protected &prot, Private &priv) {
     64     a + pub;
     65     a + prot; // expected-error {{'operator+' is a protected member}}
     66     a + priv; // expected-error {{'operator+' is a private member}}
     67     a[pub];
     68     a[prot]; // expected-error {{'operator[]' is a protected member}}
     69     a[priv]; // expected-error {{'operator[]' is a private member}}
     70     a(pub);
     71     a(prot); // expected-error {{'operator()' is a protected member}}
     72     a(priv); // expected-error {{'operator()' is a private member}}
     73     -a;       // expected-error {{'operator-' is a private member}}
     74 
     75     const A &ca = a;
     76     ca + pub;
     77     ca + prot;
     78     ca + priv;
     79     -ca;
     80     // These are all surrogate calls
     81     ca(pub);
     82     ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}}
     83     ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
     84   }
     85 }
     86 
     87 // Implicit constructor calls.
     88 namespace test2 {
     89   class A {
     90   private:
     91     A(); // expected-note 3 {{declared private here}}
     92 
     93     static A foo;
     94   };
     95 
     96   A a; // expected-error {{calling a private constructor}}
     97   A A::foo; // okay
     98 
     99   class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}}
    100   B b; // expected-note{{implicit default constructor}}
    101 
    102   class C : virtual A {
    103   public:
    104     C();
    105   };
    106 
    107   class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}}
    108   D d; // expected-note{{implicit default constructor}}
    109 }
    110 
    111 // Implicit destructor calls.
    112 namespace test3 {
    113   class A {
    114   private:
    115     ~A(); // expected-note 2 {{declared private here}}
    116     static A foo;
    117   };
    118 
    119   A a; // expected-error {{variable of type 'test3::A' has private destructor}}
    120   A A::foo;
    121 
    122   void foo(A param) { // okay
    123     A local; // expected-error {{variable of type 'test3::A' has private destructor}}
    124   }
    125 
    126   template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
    127   class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
    128                                                // expected-error {{base class 'Base<2>' has private destructor}}
    129   class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
    130 
    131   // These don't cause diagnostics because we don't need the destructor.
    132   class Derived0 : Base<0> { ~Derived0(); };
    133   class Derived1 : Base<1> { };
    134 
    135   class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
    136                    // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
    137     Base<0>,  // expected-error {{base class 'Base<0>' has private destructor}}
    138     virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
    139     Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
    140     virtual Base3
    141   {
    142     ~Derived2() {}
    143   };
    144 
    145   class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
    146                    // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}} \
    147     // expected-note 2{{implicit default constructor}}
    148     Base<0>,  // expected-error 2 {{base class 'Base<0>' has private destructor}}
    149     virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
    150     Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
    151     virtual Base3
    152   {};
    153   Derived3 d3; // expected-note {{implicit default constructor}}\
    154                // expected-note{{implicit default destructor}}}
    155 }
    156 
    157 // Conversion functions.
    158 namespace test4 {
    159   class Base {
    160   private:
    161     operator Private(); // expected-note 4 {{declared private here}}
    162   public:
    163     operator Public(); // expected-note 2{{member is declared here}}
    164   };
    165 
    166   class Derived1 : private Base { // expected-note 2 {{declared private here}} \
    167                                   // expected-note {{constrained by private inheritance}}
    168     Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
    169     Public test2() { return *this; }
    170   };
    171   Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
    172                                            // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
    173   Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
    174                                           // expected-error {{'operator Public' is a private member}}
    175 
    176 
    177   class Derived2 : public Base {
    178     Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
    179     Public test2() { return *this; }
    180   };
    181   Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
    182   Public test2(Derived2 &d) { return d; }
    183 
    184   class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
    185                                   // expected-note {{declared private here}}
    186   public:
    187     operator Private();
    188   };
    189   Private test1(Derived3 &d) { return d; }
    190   Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
    191                                           // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
    192 
    193   class Derived4 : public Base {
    194   public:
    195     operator Private();
    196   };
    197   Private test1(Derived4 &d) { return d; }
    198   Public test2(Derived4 &d) { return d; }
    199 }
    200 
    201 // Implicit copy assignment operator uses.
    202 namespace test5 {
    203   class A {
    204     void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
    205   };
    206 
    207   class Test1 { A a; }; // expected-error {{private member}}
    208   void test1() {
    209     Test1 a;
    210     a = Test1(); // expected-note{{implicit default copy}}
    211   }
    212 
    213   class Test2 : A {}; // expected-error {{private member}}
    214   void test2() {
    215     Test2 a;
    216     a = Test2(); // expected-note{{implicit default copy}}
    217   }
    218 }
    219 
    220 // Implicit copy constructor uses.
    221 namespace test6 {
    222   class A {
    223     public: A();
    224     private: A(const A &); // expected-note 2 {{declared private here}}
    225   };
    226 
    227   class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
    228   void test1(const Test1 &t) {
    229     Test1 a = t; // expected-note{{implicit default copy}}
    230   }
    231 
    232   class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
    233   void test2(const Test2 &t) {
    234     Test2 a = t; // expected-note{{implicit default copy}}
    235   }
    236 }
    237 
    238 // Redeclaration lookups are not accesses.
    239 namespace test7 {
    240   class A {
    241     int private_member;
    242   };
    243   class B : A {
    244     int foo(int private_member) {
    245       return 0;
    246     }
    247   };
    248 }
    249 
    250 // Ignored operator new and delete overloads are not
    251 namespace test8 {
    252   typedef __typeof__(sizeof(int)) size_t;
    253 
    254   class A {
    255     void *operator new(size_t s);
    256     void operator delete(void *p);
    257   public:
    258     void *operator new(size_t s, int n);
    259     void operator delete(void *p, int n);
    260   };
    261 
    262   void test() {
    263     new (2) A();
    264   }
    265 }
    266 
    267 // Don't silently upgrade forbidden-access paths to private.
    268 namespace test9 {
    269   class A {
    270   public: static int x; // expected-note {{member is declared here}}
    271   };
    272   class B : private A { // expected-note {{constrained by private inheritance here}}
    273   };
    274   class C : public B {
    275     static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
    276   };
    277 }
    278 
    279 namespace test10 {
    280   class A {
    281     enum {
    282       value = 10 // expected-note {{declared private here}}
    283     };
    284     friend class C;
    285   };
    286 
    287   class B {
    288     enum {
    289       value = A::value // expected-error {{'value' is a private member of 'test10::A'}}
    290     };
    291   };
    292 
    293   class C {
    294     enum {
    295       value = A::value
    296     };
    297   };
    298 }
    299 
    300 namespace test11 {
    301   class A {
    302     protected: virtual ~A();
    303   };
    304 
    305   class B : public A {
    306     ~B();
    307   };
    308 
    309   B::~B() {};
    310 }
    311 
    312 namespace test12 {
    313   class A {
    314     int x;
    315 
    316     void foo() {
    317       class Local {
    318         int foo(A *a) {
    319           return a->x;
    320         }
    321       };
    322     }
    323   };
    324 }
    325 
    326 namespace test13 {
    327   struct A {
    328     int x;
    329     unsigned foo() const;
    330   };
    331 
    332   struct B : protected A {
    333     using A::foo;
    334     using A::x;
    335   };
    336 
    337   void test() {
    338     A *d;
    339     d->foo();
    340     (void) d->x;
    341   }
    342 }
    343 
    344 // Destructors for temporaries.
    345 namespace test14 {
    346   class A {
    347   private: ~A(); // expected-note {{declared private here}}
    348   };
    349   A foo();
    350 
    351   void test() {
    352     foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
    353   }
    354 
    355   class X {
    356     ~X(); // expected-note {{declared private here}}
    357   };
    358 
    359   struct Y1 {
    360     operator X();
    361   };
    362 
    363   void g() {
    364     const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}}
    365   }
    366 }
    367 
    368 // PR 7024
    369 namespace test15 {
    370   template <class T> class A {
    371   private:
    372     int private_foo; // expected-note {{declared private here}}
    373     static int private_sfoo; // expected-note {{declared private here}}
    374   protected:
    375     int protected_foo; // expected-note 3 {{declared protected here}} // expected-note {{can only access this member on an object of type 'test15::B<int>'}}
    376     static int protected_sfoo; // expected-note 3 {{declared protected here}}
    377 
    378     int test1(A<int> &a) {
    379       return a.private_foo; // expected-error {{private member}}
    380     }
    381 
    382     int test2(A<int> &a) {
    383       return a.private_sfoo; // expected-error {{private member}}
    384     }
    385 
    386     int test3(A<int> &a) {
    387       return a.protected_foo; // expected-error {{protected member}}
    388     }
    389 
    390     int test4(A<int> &a) {
    391       return a.protected_sfoo; // expected-error {{protected member}}
    392     }
    393   };
    394 
    395   template class A<int>;
    396   template class A<long>; // expected-note 4 {{in instantiation}}
    397 
    398   template <class T> class B : public A<T> {
    399     // TODO: These first two accesses can be detected as ill-formed at
    400     // definition time because they're member accesses and A<int> can't
    401     // be a subclass of B<T> for any T.
    402 
    403     int test1(A<int> &a) {
    404       return a.protected_foo; // expected-error 2 {{protected member}}
    405     }
    406 
    407     int test2(A<int> &a) {
    408       return a.protected_sfoo; // expected-error {{protected member}}
    409     }
    410 
    411     int test3(B<int> &b) {
    412       return b.protected_foo; // expected-error {{protected member}}
    413     }
    414 
    415     int test4(B<int> &b) {
    416       return b.protected_sfoo; // expected-error {{protected member}}
    417     }
    418   };
    419 
    420   template class B<int>;  // expected-note {{in instantiation}}
    421   template class B<long>; // expected-note 4 {{in instantiation}}
    422 }
    423 
    424 // PR7281
    425 namespace test16 {
    426   class A { ~A(); }; // expected-note 2{{declared private here}}
    427   void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \
    428   // expected-error{{exception object of type 'test16::A' has private destructor}}
    429 }
    430 
    431 // rdar://problem/8146294
    432 namespace test17 {
    433   class A {
    434     template <typename T> class Inner { }; // expected-note {{declared private here}}
    435   };
    436 
    437   A::Inner<int> s; // expected-error {{'Inner' is a private member of 'test17::A'}}
    438 }
    439 
    440 namespace test18 {
    441   template <class T> class A {};
    442   class B : A<int> {
    443     A<int> member;
    444   };
    445 
    446   // FIXME: this access to A should be forbidden (because C++ is dumb),
    447   // but LookupResult can't express the necessary information to do
    448   // the check, so we aggressively suppress access control.
    449   class C : B {
    450     A<int> member;
    451   };
    452 }
    453 
    454 // PR8325
    455 namespace test19 {
    456   class A { ~A(); };
    457   // The destructor is not implicitly referenced here.  Contrast to test16,
    458   // testing PR7281, earlier in this file.
    459   void b(A* x) { throw x; }
    460 }
    461 
    462 // PR7930
    463 namespace test20 {
    464   class Foo {
    465     Foo(); // expected-note {{implicitly declared private here}}
    466   };
    467   Foo::Foo() {}
    468 
    469   void test() {
    470     Foo a; // expected-error {{calling a private constructor}}
    471   }
    472 }
    473 
    474 namespace test21 {
    475   template <class T> class A {
    476     void foo();
    477     void bar();
    478     class Inner; // expected-note {{implicitly declared private here}}
    479   public:
    480     void baz();
    481   };
    482   template <class T> class A<T>::Inner {};
    483   class B {
    484     template <class T> class A<T>::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}}
    485   };
    486 
    487   void test() {
    488     A<int>::Inner i; // expected-error {{'Inner' is a private member}}
    489   }
    490 }
    491 
    492 namespace rdar8876150 {
    493   struct A { operator bool(); };
    494   struct B : private A { using A::operator bool; };
    495 
    496   bool f() {
    497     B b;
    498     return !b;
    499   }
    500 }
    501 
    502 namespace test23 {
    503   template <typename T> class A {
    504     A();
    505     static A instance;
    506   };
    507 
    508   template <typename T> A<T> A<T>::instance;
    509   template class A<int>;
    510 }
    511