Home | History | Annotate | Download | only in class.protected
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 namespace test0 {
      4   class A {
      5     protected: int x; // expected-note 3 {{declared}} \
      6     // expected-note {{member is declared here}}
      7     static int sx; // expected-note 3 {{declared}} \
      8     // expected-note {{member is declared here}}
      9   };
     10   class B : public A {
     11   };
     12   class C : protected A { // expected-note {{declared}}
     13   };
     14   class D : private B { // expected-note 3 {{constrained}}
     15   };
     16 
     17   void test(A &a) {
     18     (void) a.x; // expected-error {{'x' is a protected member}}
     19     (void) a.sx; // expected-error {{'sx' is a protected member}}
     20   }
     21   void test(B &b) {
     22     (void) b.x; // expected-error {{'x' is a protected member}}
     23     (void) b.sx; // expected-error {{'sx' is a protected member}}
     24   }
     25   void test(C &c) {
     26     (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}}
     27     (void) c.sx; // expected-error {{'sx' is a protected member}}
     28   }
     29   void test(D &d) {
     30     (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}}
     31     (void) d.sx; // expected-error {{'sx' is a private member}}
     32   }
     33 }
     34 
     35 namespace test1 {
     36   class A {
     37     protected: int x;
     38     static int sx;
     39     static void test(A&);
     40   };
     41   class B : public A {
     42     static void test(B&);
     43   };
     44   class C : protected A {
     45     static void test(C&);
     46   };
     47   class D : private B {
     48     static void test(D&);
     49   };
     50 
     51   void A::test(A &a) {
     52     (void) a.x;
     53     (void) a.sx;
     54   }
     55   void B::test(B &b) {
     56     (void) b.x;
     57     (void) b.sx;
     58   }
     59   void C::test(C &c) {
     60     (void) c.x;
     61     (void) c.sx;
     62   }
     63   void D::test(D &d) {
     64     (void) d.x;
     65     (void) d.sx;
     66   }
     67 }
     68 
     69 namespace test2 {
     70   class A {
     71     protected: int x; // expected-note 3 {{can only access this member on an object of type}}
     72     static int sx;
     73     static void test(A&);
     74   };
     75   class B : public A {
     76     static void test(A&);
     77   };
     78   class C : protected A {
     79     static void test(A&);
     80   };
     81   class D : private B {
     82     static void test(A&);
     83   };
     84 
     85   void A::test(A &a) {
     86     (void) a.x;
     87     (void) a.sx;
     88   }
     89   void B::test(A &a) {
     90     (void) a.x; // expected-error {{'x' is a protected member}}
     91     (void) a.sx;
     92   }
     93   void C::test(A &a) {
     94     (void) a.x; // expected-error {{'x' is a protected member}}
     95     (void) a.sx;
     96   }
     97   void D::test(A &a) {
     98     (void) a.x; // expected-error {{'x' is a protected member}}
     99     (void) a.sx;
    100   }
    101 }
    102 
    103 namespace test3 {
    104   class B;
    105   class A {
    106     protected: int x; //expected-note {{declared protected}} // expected-note {{can only access this member on an object of type}}
    107     static int sx;
    108     static void test(B&);
    109   };
    110   class B : public A {
    111     static void test(B&);
    112   };
    113   class C : protected A {
    114     static void test(B&);
    115   };
    116   class D : private B {
    117     static void test(B&);
    118   };
    119 
    120   void A::test(B &b) {
    121     (void) b.x;
    122     (void) b.sx;
    123   }
    124   void B::test(B &b) {
    125     (void) b.x;
    126     (void) b.sx;
    127   }
    128   void C::test(B &b) {
    129     (void) b.x; // expected-error {{'x' is a protected member}}
    130     (void) b.sx;
    131   }
    132   void D::test(B &b) {
    133     (void) b.x; // expected-error {{'x' is a protected member}}
    134     (void) b.sx;
    135   }
    136 }
    137 
    138 namespace test4 {
    139   class C;
    140   class A {
    141     protected: int x; // expected-note 2{{declared protected here}} expected-note{{member is declared here}}
    142     static int sx;    // expected-note 3{{member is declared here}}
    143     static void test(C&);
    144   };
    145   class B : public A {
    146     static void test(C&);
    147   };
    148   class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}}
    149     static void test(C&);
    150   };
    151   class D : private B {
    152     static void test(C&);
    153   };
    154 
    155   void A::test(C &c) {
    156     (void) c.x;  // expected-error {{'x' is a protected member}} \
    157                  // expected-error {{protected base class}}
    158     (void) c.sx; // expected-error {{'sx' is a protected member}}
    159   }
    160   void B::test(C &c) {
    161     (void) c.x;  // expected-error {{'x' is a protected member}} \
    162                  // expected-error {{protected base class}}
    163     (void) c.sx; // expected-error {{'sx' is a protected member}}
    164   }
    165   void C::test(C &c) {
    166     (void) c.x;
    167     (void) c.sx;
    168   }
    169   void D::test(C &c) {
    170     (void) c.x;  // expected-error {{'x' is a protected member}} \
    171                  // expected-error {{protected base class}}
    172     (void) c.sx; // expected-error {{'sx' is a protected member}}
    173   }
    174 }
    175 
    176 namespace test5 {
    177   class D;
    178   class A {
    179     protected: int x; // expected-note 3{{member is declared here}}
    180     static int sx; // expected-note 3{{member is declared here}}
    181     static void test(D&);
    182   };
    183   class B : public A {
    184     static void test(D&);
    185   };
    186   class C : protected A {
    187     static void test(D&);
    188   };
    189   class D : private B { // expected-note 9 {{constrained}}
    190     static void test(D&);
    191   };
    192 
    193   void A::test(D &d) {
    194     (void) d.x;  // expected-error {{'x' is a private member}} \
    195                  // expected-error {{cannot cast}}
    196     (void) d.sx; // expected-error {{'sx' is a private member}}
    197   }
    198   void B::test(D &d) {
    199     (void) d.x;  // expected-error {{'x' is a private member}} \
    200                  // expected-error {{cannot cast}}
    201     (void) d.sx; // expected-error {{'sx' is a private member}}
    202   }
    203   void C::test(D &d) {
    204     (void) d.x;  // expected-error {{'x' is a private member}} \
    205                  // expected-error {{cannot cast}}
    206     (void) d.sx; // expected-error {{'sx' is a private member}}
    207   }
    208   void D::test(D &d) {
    209     (void) d.x;
    210     (void) d.sx;
    211   }
    212 }
    213 
    214 namespace test6 {
    215   class Static {};
    216   class A {
    217   protected:
    218     void foo(int); // expected-note 3 {{can only access this member on an object of type}}
    219     void foo(long);
    220     static void foo(Static);
    221 
    222     static void test(A&);
    223   };
    224   class B : public A {
    225     static void test(A&);
    226   };
    227   class C : protected A {
    228     static void test(A&);
    229   };
    230   class D : private B {
    231     static void test(A&);
    232   };
    233 
    234   void A::test(A &a) {
    235     a.foo(10);
    236     a.foo(Static());
    237   }
    238   void B::test(A &a) {
    239     a.foo(10); // expected-error {{'foo' is a protected member}}
    240     a.foo(Static());
    241   }
    242   void C::test(A &a) {
    243     a.foo(10); // expected-error {{'foo' is a protected member}}
    244     a.foo(Static());
    245   }
    246   void D::test(A &a) {
    247     a.foo(10); // expected-error {{'foo' is a protected member}}
    248     a.foo(Static());
    249   }
    250 }
    251 
    252 namespace test7 {
    253   class Static {};
    254   class A {
    255     protected:
    256     void foo(int); // expected-note 3 {{must name member using the type of the current context}}
    257     void foo(long);
    258     static void foo(Static);
    259 
    260     static void test();
    261   };
    262   class B : public A {
    263     static void test();
    264   };
    265   class C : protected A {
    266     static void test();
    267   };
    268   class D : private B {
    269     static void test();
    270   };
    271 
    272   void A::test() {
    273     void (A::*x)(int) = &A::foo;
    274     void (*sx)(Static) = &A::foo;
    275   }
    276   void B::test() {
    277     void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
    278     void (*sx)(Static) = &A::foo;
    279   }
    280   void C::test() {
    281     void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
    282     void (*sx)(Static) = &A::foo;
    283   }
    284   void D::test() {
    285     void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}}
    286     void (*sx)(Static) = &A::foo;
    287   }
    288 }
    289 
    290 namespace test8 {
    291   class Static {};
    292   class A {
    293     protected:
    294     void foo(int); // expected-note 3 {{must name member using the type of the current context}}
    295     void foo(long);
    296     static void foo(Static);
    297 
    298     static void test();
    299   };
    300   class B : public A {
    301     static void test();
    302   };
    303   class C : protected A {
    304     static void test();
    305   };
    306   class D : private B {
    307     static void test();
    308   };
    309   void call(void (A::*)(int));
    310   void calls(void (*)(Static));
    311 
    312   void A::test() {
    313     call(&A::foo);
    314     calls(&A::foo);
    315   }
    316   void B::test() {
    317     call(&A::foo); // expected-error {{'foo' is a protected member}}
    318     calls(&A::foo);
    319   }
    320   void C::test() {
    321     call(&A::foo); // expected-error {{'foo' is a protected member}}
    322     calls(&A::foo);
    323   }
    324   void D::test() {
    325     call(&A::foo); // expected-error {{'foo' is a protected member}}
    326     calls(&A::foo);
    327   }
    328 }
    329 
    330 namespace test9 {
    331   class A { // expected-note {{member is declared here}}
    332   protected: int foo(); // expected-note 4 {{declared}} expected-note 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}}
    333   };
    334 
    335   class B : public A { // expected-note {{member is declared here}}
    336     friend class D;
    337   };
    338 
    339   class C : protected B { // expected-note {{declared}} \
    340                           // expected-note 9 {{constrained}}
    341   };
    342 
    343   class D : public A {
    344     static void test(A &a) {
    345       a.foo(); // expected-error {{'foo' is a protected member}}
    346       a.A::foo(); // expected-error {{'foo' is a protected member}}
    347       a.B::foo(); // expected-error {{'foo' is a protected member}}
    348       a.C::foo(); // expected-error {{'foo' is a protected member}}
    349       a.D::foo(); // expected-error {{'foo' is a protected member}}
    350     }
    351 
    352     static void test(B &b) {
    353       b.foo();
    354       b.A::foo();
    355       b.B::foo(); // accessible as named in A
    356       b.C::foo(); // expected-error {{'foo' is a protected member}}
    357     }
    358 
    359     static void test(C &c) {
    360       c.foo();    // expected-error {{'foo' is a protected member}} \
    361                   // expected-error {{cannot cast}}
    362       c.A::foo(); // expected-error {{'A' is a protected member}} \
    363                   // expected-error {{cannot cast}}
    364       c.B::foo(); // expected-error {{'B' is a protected member}} \
    365                   // expected-error {{cannot cast}}
    366       c.C::foo(); // expected-error {{'foo' is a protected member}} \
    367                   // expected-error {{cannot cast}}
    368     }
    369 
    370     static void test(D &d) {
    371       d.foo();
    372       d.A::foo();
    373       d.B::foo();
    374       d.C::foo(); // expected-error {{'foo' is a protected member}}
    375     }
    376   };
    377 }
    378 
    379 namespace test10 {
    380   template<typename T> class A {
    381   protected:
    382     int foo();
    383     int foo() const;
    384 
    385     ~A() { foo(); }
    386   };
    387 
    388   template class A<int>;
    389 }
    390 
    391 // rdar://problem/8360285: class.protected friendship
    392 namespace test11 {
    393   class A {
    394   protected:
    395     int foo();
    396   };
    397 
    398   class B : public A {
    399     friend class C;
    400   };
    401 
    402   class C {
    403     void test() {
    404       B b;
    405       b.A::foo();
    406     }
    407   };
    408 }
    409 
    410 // This friendship is considered because a public member of A would be
    411 // a private member of C.
    412 namespace test12 {
    413   class A { protected: int foo(); };
    414   class B : public virtual A {};
    415   class C : private B { friend void test(); };
    416   class D : private C, public virtual A {};
    417 
    418   void test() {
    419     D d;
    420     d.A::foo();
    421   }
    422 }
    423 
    424 // This friendship is not considered because a public member of A is
    425 // inaccessible in C.
    426 namespace test13 {
    427   class A { protected: int foo(); }; // expected-note {{declared protected here}}
    428   class B : private virtual A {};
    429   class C : private B { friend void test(); };
    430   class D : public virtual A {};
    431 
    432   void test() {
    433     D d;
    434     d.A::foo(); // expected-error {{protected member}}
    435   }
    436 }
    437 
    438 // PR8058
    439 namespace test14 {
    440   class A {
    441   protected:
    442     template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}}
    443 
    444     void nontemp(int); // expected-note {{must name member using the type of the current context}}
    445 
    446     template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}}
    447     void ovl_temp(float);
    448 
    449     void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}}
    450     void ovl_nontemp(float);
    451 
    452     template <class T> void ovl_withtemp(T);
    453     void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}}
    454   };
    455 
    456   class B : public A {
    457     void use() {
    458       void (A::*ptr)(int);
    459       ptr = &A::temp; // expected-error {{protected member}}
    460       ptr = &A::nontemp; // expected-error {{protected member}}
    461       ptr = &A::ovl_temp; // expected-error {{protected member}}
    462       ptr = &A::ovl_nontemp; // expected-error {{protected member}}
    463       ptr = &A::ovl_withtemp; // expected-error {{protected member}}
    464     }
    465   };
    466 }
    467 
    468 namespace test15 {
    469   class A {
    470   protected:
    471     A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}}
    472     A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}}
    473     ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}}
    474   };
    475 
    476   class B : public A {
    477     // The uses here are fine.
    478     B() {}
    479     B(int i) : A() {}
    480     ~B() {}
    481 
    482     // All these uses are bad.
    483 
    484     void test0() {
    485       A a; // expected-error {{protected constructor}} expected-error {{protected destructor}}
    486     }
    487 
    488     A *test1() {
    489       return new A(); // expected-error {{protected constructor}}
    490     }
    491 
    492     void test2(A *a) {
    493       delete a; // expected-error {{protected destructor}}
    494     }
    495 
    496     A test3(A *a) {
    497       return *a; // expected-error {{protected constructor}}
    498     }
    499 
    500     void test4(A *a) {
    501       a->~A(); // expected-error {{protected member}}
    502     }
    503   };
    504 }
    505 
    506 namespace test16 {
    507   class A {
    508   protected:
    509     ~A();
    510   };
    511 
    512   class B : public virtual A {
    513   public:
    514     ~B() {}
    515   };
    516 
    517   class C : public B {
    518     ~C() {}
    519   };
    520 }
    521