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