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