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 | |
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}} |
20 | static int test() { return x; } |
21 | }; |
22 | struct B : public A { |
23 | static int test() { return x; } // expected-error {{private member}} |
24 | }; |
25 | struct C : private A { |
26 | 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}} |
31 | static int test() { return x; } |
32 | }; |
33 | struct E : private D { // expected-note{{constrained by private inheritance}} |
34 | static int test() { return x; } |
35 | }; |
36 | |
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 { |
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 { |
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 | |
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 | |