1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // C++0x [class.access.base]p1(a):
4 //   If a class is declared to be a base class for another class using
5 //   the public access specifier, the public members of the base class
6 //   are accessible as public members of the derived class and protected
7 //   members of the base class are accessible as protected members of
8 //   the derived class.
9 namespace test0 {
10   class Base {
11   public: int pub; static int spub;
12   protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
13   private: int priv; static int spriv; // expected-note 8 {{declared private here}}
14   };
15 
16   class Test : public Base {
test()17     void test() {
18       pub++;
19       spub++;
20       prot++;
21       sprot++;
22       priv++; // expected-error {{private member}}
23       spriv++; // expected-error {{private member}}
24 
25       Base::pub++;
26       Base::spub++;
27       Base::prot++;
28       Base::sprot++;
29       Base::priv++; // expected-error {{private member}}
30       Base::spriv++; // expected-error {{private member}}
31     }
32   };
33 
test(Test * t)34   void test(Test *t) {
35     t->pub++;
36     t->spub++;
37     t->prot++; // expected-error {{protected member}}
38     t->sprot++; // expected-error {{protected member}}
39     t->priv++; // expected-error {{private member}}
40     t->spriv++; // expected-error {{private member}}
41 
42     t->Base::pub++;
43     t->Base::spub++;
44     t->Base::prot++; // expected-error {{protected member}}
45     t->Base::sprot++; // expected-error {{protected member}}
46     t->Base::priv++; // expected-error {{private member}}
47     t->Base::spriv++; // expected-error {{private member}}
48   }
49 }
50 
51 // C++0x [class.access.base]p1(b):
52 //   If a class is declared to be a base class for another class using
53 //   the protected access specifier, the public and protected members
54 //   of the base class are accessible as protected members of the
55 //   derived class.
56 namespace test1 {
57   class Base { // expected-note 6{{member is declared here}}
58   public:
59     int pub; // expected-note{{member is declared here}}
60     static int spub; // expected-note{{member is declared here}}
61   protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
62   private: int priv; static int spriv; // expected-note 8 {{declared private here}}
63   };
64 
65   class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
test()66     void test() {
67       pub++;
68       spub++;
69       prot++;
70       sprot++;
71       priv++; // expected-error {{private member}}
72       spriv++; // expected-error {{private member}}
73 
74       Base::pub++;
75       Base::spub++;
76       Base::prot++;
77       Base::sprot++;
78       Base::priv++; // expected-error {{private member}}
79       Base::spriv++; // expected-error {{private member}}
80     }
81   };
82 
test(Test * t)83   void test(Test *t) {
84     t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
85     t->spub++; // expected-error {{protected member}}
86     t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
87     t->sprot++; // expected-error {{protected member}}
88     t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
89     t->spriv++; // expected-error {{private member}}
90 
91     // Two possible errors here: one for Base, one for the member
92     t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
93     t->Base::spub++; // expected-error {{protected member}}
94     t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
95     t->Base::sprot++; // expected-error 2 {{protected member}}
96     t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
97     t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
98   }
99 }
100 
101 // C++0x [class.access.base]p1(b):
102 //   If a class is declared to be a base class for another class using
103 //   the private access specifier, the public and protected members of
104 //   the base class are accessible as private members of the derived
105 //   class.
106 namespace test2 {
107   class Base { // expected-note 6{{member is declared here}}
108   public:
109     int pub; // expected-note{{member is declared here}}
110     static int spub; // expected-note{{member is declared here}}
111   protected:
112     int prot; // expected-note {{declared protected here}} \
113     // expected-note{{member is declared here}}
114     static int sprot; // expected-note {{declared protected here}} \
115     // expected-note{{member is declared here}}
116   private:
117     int priv; // expected-note 4 {{declared private here}}
118     static int spriv; // expected-note 4 {{declared private here}}
119   };
120 
121   class Test : private Base { // expected-note 6 {{declared private here}} \
122                               // expected-note 10 {{constrained by private inheritance here}}
test()123     void test() {
124       pub++;
125       spub++;
126       prot++;
127       sprot++;
128       priv++; // expected-error {{private member}}
129       spriv++; // expected-error {{private member}}
130 
131       Base::pub++;
132       Base::spub++;
133       Base::prot++;
134       Base::sprot++;
135       Base::priv++; // expected-error {{private member}}
136       Base::spriv++; // expected-error {{private member}}
137     }
138   };
139 
test(Test * t)140   void test(Test *t) {
141     t->pub++; // expected-error {{private member}} expected-error {{private base class}}
142     t->spub++; // expected-error {{private member}}
143     t->prot++; // expected-error {{private member}} expected-error {{private base class}}
144     t->sprot++; // expected-error {{private member}}
145     t->priv++; // expected-error {{private member}} expected-error {{private base class}}
146     t->spriv++; // expected-error {{private member}}
147 
148     t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
149     t->Base::spub++; // expected-error {{private member}}
150     t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
151     t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
152     t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
153     t->Base::spriv++; // expected-error 2 {{private member}}
154   }
155 }
156 
157 namespace PR12788 {
158   class A {
159   protected:
160     struct {
161       int x;
162     };
163   };
164   class B : A {
f()165     void f() {
166       ++x;
167       A::x++;
168     }
169   };
170 }
171