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 {{object type must derive}}
     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 {{object type must derive}}
    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;
    134     (void) b.sx;
    135   }
    136 }
    137 
    138 namespace test4 {
    139   class C;
    140   class A {
    141     protected: int x; // expected-note {{declared}} expected-note 2 {{object type must derive}}
    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 {{object type must derive}}
    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 {{object type must derive}}
    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 {{object type must derive}}
    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 2 {{object type must derive}} expected-note {{object type 'test9::A' must derive}}
    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();
    348       a.C::foo(); // expected-error {{'foo' is a protected member}}
    349     }
    350 
    351     static void test(B &b) {
    352       b.foo();
    353       b.A::foo();
    354       b.B::foo();
    355       b.C::foo(); // expected-error {{'foo' is a protected member}}
    356     }
    357 
    358     static void test(C &c) {
    359       c.foo();    // expected-error {{'foo' is a protected member}} \
    360                   // expected-error {{cannot cast}}
    361       c.A::foo(); // expected-error {{'A' is a protected member}} \
    362                   // expected-error {{cannot cast}}
    363       c.B::foo(); // expected-error {{'B' is a protected member}} \
    364                   // expected-error {{cannot cast}}
    365       c.C::foo(); // expected-error {{'foo' is a protected member}} \
    366                   // expected-error {{cannot cast}}
    367     }
    368 
    369     static void test(D &d) {
    370       d.foo();
    371       d.A::foo();
    372       d.B::foo();
    373       d.C::foo(); // expected-error {{'foo' is a protected member}}
    374     }
    375   };
    376 }
    377 
    378 namespace test10 {
    379   template<typename T> class A {
    380   protected:
    381     int foo();
    382     int foo() const;
    383 
    384     ~A() { foo(); }
    385   };
    386 
    387   template class A<int>;
    388 }
    389 
    390 // rdar://problem/8360285: class.protected friendship
    391 namespace test11 {
    392   class A {
    393   protected:
    394     int foo();
    395   };
    396 
    397   class B : public A {
    398     friend class C;
    399   };
    400 
    401   class C {
    402     void test() {
    403       B b;
    404       b.A::foo();
    405     }
    406   };
    407 }
    408 
    409 // This friendship is considered because a public member of A would be
    410 // a private member of C.
    411 namespace test12 {
    412   class A { protected: int foo(); };
    413   class B : public virtual A {};
    414   class C : private B { friend void test(); };
    415   class D : private C, public virtual A {};
    416 
    417   void test() {
    418     D d;
    419     d.A::foo();
    420   }
    421 }
    422 
    423 // This friendship is not considered because a public member of A is
    424 // inaccessible in C.
    425 namespace test13 {
    426   class A { protected: int foo(); }; // expected-note {{object type 'test13::D' must derive from context type 'test13::C'}}
    427   class B : private virtual A {};
    428   class C : private B { friend void test(); };
    429   class D : public virtual A {};
    430 
    431   void test() {
    432     D d;
    433     d.A::foo(); // expected-error {{protected member}}
    434   }
    435 }
    436