xref: /aosp_15_r20/external/clang/test/CXX/class.access/class.access.base/p5.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li namespace test0 {
4*67e74705SXin Li   struct A {
5*67e74705SXin Li     static int x;
6*67e74705SXin Li   };
7*67e74705SXin Li   struct B : A {};
8*67e74705SXin Li   struct C : B {};
9*67e74705SXin Li 
test()10*67e74705SXin Li   int test() {
11*67e74705SXin Li     return A::x
12*67e74705SXin Li          + B::x
13*67e74705SXin Li          + C::x;
14*67e74705SXin Li   }
15*67e74705SXin Li }
16*67e74705SXin Li 
17*67e74705SXin Li namespace test1 {
18*67e74705SXin Li   struct A {
19*67e74705SXin Li     private: static int x; // expected-note 5 {{declared private here}}
testtest1::A20*67e74705SXin Li     static int test() { return x; }
21*67e74705SXin Li   };
22*67e74705SXin Li   struct B : public A {
testtest1::B23*67e74705SXin Li     static int test() { return x; } // expected-error {{private member}}
24*67e74705SXin Li   };
25*67e74705SXin Li   struct C : private A {
testtest1::C26*67e74705SXin Li     static int test() { return x; } // expected-error {{private member}}
27*67e74705SXin Li   };
28*67e74705SXin Li 
29*67e74705SXin Li   struct D {
30*67e74705SXin Li     public: static int x; // expected-note{{member is declared here}}
testtest1::D31*67e74705SXin Li     static int test() { return x; }
32*67e74705SXin Li   };
33*67e74705SXin Li   struct E : private D { // expected-note{{constrained by private inheritance}}
testtest1::E34*67e74705SXin Li     static int test() { return x; }
35*67e74705SXin Li   };
36*67e74705SXin Li 
test()37*67e74705SXin Li   int test() {
38*67e74705SXin Li     return A::x // expected-error {{private member}}
39*67e74705SXin Li          + B::x // expected-error {{private member}}
40*67e74705SXin Li          + C::x // expected-error {{private member}}
41*67e74705SXin Li          + D::x
42*67e74705SXin Li          + E::x; // expected-error {{private member}}
43*67e74705SXin Li   }
44*67e74705SXin Li }
45*67e74705SXin Li 
46*67e74705SXin Li namespace test2 {
47*67e74705SXin Li   class A {
48*67e74705SXin Li   protected: static int x; // expected-note{{member is declared here}}
49*67e74705SXin Li   };
50*67e74705SXin Li 
51*67e74705SXin Li   class B : private A {}; // expected-note {{private inheritance}}
52*67e74705SXin Li   class C : private A {
test(B * b)53*67e74705SXin Li     int test(B *b) {
54*67e74705SXin Li       return b->x; // expected-error {{private member}}
55*67e74705SXin Li     }
56*67e74705SXin Li   };
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li namespace test3 {
60*67e74705SXin Li   class A {
61*67e74705SXin Li   protected: static int x;
62*67e74705SXin Li   };
63*67e74705SXin Li 
64*67e74705SXin Li   class B : public A {};
65*67e74705SXin Li   class C : private A {
test(B * b)66*67e74705SXin Li     int test(B *b) {
67*67e74705SXin Li       // x is accessible at C when named in A.
68*67e74705SXin Li       // A is an accessible base of B at C.
69*67e74705SXin Li       // Therefore this succeeds.
70*67e74705SXin Li       return b->x;
71*67e74705SXin Li     }
72*67e74705SXin Li   };
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li // Don't crash. <rdar://12926092>
76*67e74705SXin Li // Note that 'field' is indeed a private member of X but that access
77*67e74705SXin Li // is indeed ultimately constrained by the protected inheritance from Y.
78*67e74705SXin Li // If someone wants to put the effort into improving this diagnostic,
79*67e74705SXin Li // they can feel free; even explaining it in person would be a pain.
80*67e74705SXin Li namespace test4 {
81*67e74705SXin Li   class Z;
82*67e74705SXin Li   class X {
83*67e74705SXin Li   public:
84*67e74705SXin Li     void f(Z *p);
85*67e74705SXin Li 
86*67e74705SXin Li   private:
87*67e74705SXin Li     int field; // expected-note {{member is declared here}}
88*67e74705SXin Li   };
89*67e74705SXin Li 
90*67e74705SXin Li   class Y : public X { };
91*67e74705SXin Li   class Z : protected Y { }; // expected-note 2 {{constrained by protected inheritance here}}
92*67e74705SXin Li 
f(Z * p)93*67e74705SXin Li   void X::f(Z *p) {
94*67e74705SXin Li     p->field = 0; // expected-error {{cannot cast 'test4::Z' to its protected base class 'test4::X'}} expected-error {{'field' is a private member of 'test4::X'}}
95*67e74705SXin Li   }
96*67e74705SXin Li }
97*67e74705SXin Li 
98*67e74705SXin Li // TODO: flesh out these cases
99