blob: fdde73506220d448018769ba990dca599c187af7 [file] [log] [blame]
John McCall7002f4c2010-04-09 19:03:51 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
John McCallc373d482010-01-27 01:50:18 +00002
3// C++0x [class.access]p4:
4
5// Access control is applied uniformly to all names, whether the
6// names are referred to from declarations or expressions. In the
7// case of overloaded function names, access control is applied to
8// the function selected by overload resolution.
9
10class Public {} PublicInst;
11class Protected {} ProtectedInst;
12class Private {} PrivateInst;
13
14namespace test0 {
15 class A {
16 public:
17 void foo(Public&);
18 protected:
19 void foo(Protected&); // expected-note 2 {{declared protected here}}
20 private:
21 void foo(Private&); // expected-note 2 {{declared private here}}
22 };
23
24 void test(A *op) {
25 op->foo(PublicInst);
John McCall6b2accb2010-02-10 09:31:12 +000026 op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
27 op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
John McCallc373d482010-01-27 01:50:18 +000028
29 void (A::*a)(Public&) = &A::foo;
John McCall6b2accb2010-02-10 09:31:12 +000030 void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}}
31 void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}}
John McCallc373d482010-01-27 01:50:18 +000032 }
33}
John McCall5357b612010-01-28 01:42:12 +000034
35// Member operators.
36namespace test1 {
37 class A {
38 public:
39 void operator+(Public&);
40 void operator[](Public&);
John McCall41d89032010-01-28 01:54:34 +000041 void operator()(Public&);
John McCall233a6412010-01-28 07:38:46 +000042 typedef void (*PublicSurrogate)(Public&);
43 operator PublicSurrogate() const;
John McCall5357b612010-01-28 01:42:12 +000044 protected:
45 void operator+(Protected&); // expected-note {{declared protected here}}
46 void operator[](Protected&); // expected-note {{declared protected here}}
John McCall41d89032010-01-28 01:54:34 +000047 void operator()(Protected&); // expected-note {{declared protected here}}
John McCall233a6412010-01-28 07:38:46 +000048 typedef void (*ProtectedSurrogate)(Protected&);
49 operator ProtectedSurrogate() const; // expected-note {{declared protected here}}
John McCall5357b612010-01-28 01:42:12 +000050 private:
51 void operator+(Private&); // expected-note {{declared private here}}
52 void operator[](Private&); // expected-note {{declared private here}}
John McCall41d89032010-01-28 01:54:34 +000053 void operator()(Private&); // expected-note {{declared private here}}
John McCall5357b612010-01-28 01:42:12 +000054 void operator-(); // expected-note {{declared private here}}
John McCall233a6412010-01-28 07:38:46 +000055 typedef void (*PrivateSurrogate)(Private&);
56 operator PrivateSurrogate() const; // expected-note {{declared private here}}
John McCall5357b612010-01-28 01:42:12 +000057 };
58 void operator+(const A &, Public&);
59 void operator+(const A &, Protected&);
60 void operator+(const A &, Private&);
61 void operator-(const A &);
62
63 void test(A &a, Public &pub, Protected &prot, Private &priv) {
64 a + pub;
John McCall6b2accb2010-02-10 09:31:12 +000065 a + prot; // expected-error {{'operator+' is a protected member}}
66 a + priv; // expected-error {{'operator+' is a private member}}
John McCall5357b612010-01-28 01:42:12 +000067 a[pub];
John McCall6b2accb2010-02-10 09:31:12 +000068 a[prot]; // expected-error {{'operator[]' is a protected member}}
69 a[priv]; // expected-error {{'operator[]' is a private member}}
John McCall41d89032010-01-28 01:54:34 +000070 a(pub);
John McCall6b2accb2010-02-10 09:31:12 +000071 a(prot); // expected-error {{'operator()' is a protected member}}
72 a(priv); // expected-error {{'operator()' is a private member}}
73 -a; // expected-error {{'operator-' is a private member}}
John McCall5357b612010-01-28 01:42:12 +000074
75 const A &ca = a;
76 ca + pub;
77 ca + prot;
78 ca + priv;
79 -ca;
John McCall233a6412010-01-28 07:38:46 +000080 // These are all surrogate calls
81 ca(pub);
John McCall6b2accb2010-02-10 09:31:12 +000082 ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}}
83 ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
John McCall5357b612010-01-28 01:42:12 +000084 }
85}
John McCall4f9506a2010-02-02 08:45:54 +000086
87// Implicit constructor calls.
88namespace test2 {
89 class A {
90 private:
Anders Carlsson9a68a672010-04-21 18:47:17 +000091 A(); // expected-note 3 {{declared private here}}
John McCall4f9506a2010-02-02 08:45:54 +000092
93 static A foo;
94 };
95
John McCall6b2accb2010-02-10 09:31:12 +000096 A a; // expected-error {{calling a private constructor}}
John McCall4f9506a2010-02-02 08:45:54 +000097 A A::foo; // okay
Anders Carlsson9a68a672010-04-21 18:47:17 +000098
99 class B : A { }; // expected-error {{base class 'test2::A' has private constructor}}
100 B b;
101
102 class C : virtual A {
103 public:
104 C();
105 };
Anders Carlsson711f34a2010-04-21 19:52:01 +0000106
107 class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private constructor}}
Anders Carlsson9a68a672010-04-21 18:47:17 +0000108 D d;
John McCall4f9506a2010-02-02 08:45:54 +0000109}
110
111// Implicit destructor calls.
112namespace test3 {
John McCall58e6f342010-03-16 05:22:47 +0000113 class A {
John McCall4f9506a2010-02-02 08:45:54 +0000114 private:
Douglas Gregor9c127392010-03-26 06:57:13 +0000115 ~A(); // expected-note 2 {{declared private here}}
John McCall4f9506a2010-02-02 08:45:54 +0000116 static A foo;
117 };
118
John McCall58e6f342010-03-16 05:22:47 +0000119 A a; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000120 A A::foo;
121
Douglas Gregor9c127392010-03-26 06:57:13 +0000122 void foo(A param) { // okay
John McCall58e6f342010-03-16 05:22:47 +0000123 A local; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000124 }
John McCall58e6f342010-03-16 05:22:47 +0000125
John McCallef027fe2010-03-16 21:39:52 +0000126 template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
127 class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
128 // expected-error {{base class 'Base<2>' has private destructor}}
129 class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
John McCall58e6f342010-03-16 05:22:47 +0000130
131 // These don't cause diagnostics because we don't need the destructor.
132 class Derived0 : Base<0> { ~Derived0(); };
133 class Derived1 : Base<1> { };
134
135 class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
136 // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
137 Base<0>, // expected-error {{base class 'Base<0>' has private destructor}}
138 virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
139 Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
140 virtual Base3
141 {
142 ~Derived2() {}
143 };
John McCall6c790ea2010-03-16 05:36:30 +0000144
John McCallef027fe2010-03-16 21:39:52 +0000145 class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
146 // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}}
147 Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}}
148 virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
149 Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
John McCall6c790ea2010-03-16 05:36:30 +0000150 virtual Base3
151 {};
152 Derived3 d3;
John McCall4f9506a2010-02-02 08:45:54 +0000153}
John McCallb05b5f32010-03-15 09:07:48 +0000154
155// Conversion functions.
156namespace test4 {
157 class Base {
158 private:
159 operator Private(); // expected-note 4 {{declared private here}}
160 public:
161 operator Public();
162 };
163
164 class Derived1 : private Base { // expected-note 2 {{declared private here}} \
165 // expected-note {{constrained by private inheritance}}
166 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
167 Public test2() { return *this; }
168 };
169 Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
170 // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
171 Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
172 // expected-error {{'operator Public' is a private member}}
173
174
175 class Derived2 : public Base {
176 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
177 Public test2() { return *this; }
178 };
179 Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
180 Public test2(Derived2 &d) { return d; }
181
182 class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
183 // expected-note {{declared private here}}
184 public:
185 operator Private();
186 };
187 Private test1(Derived3 &d) { return d; }
188 Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
189 // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
190
191 class Derived4 : public Base {
192 public:
193 operator Private();
194 };
195 Private test1(Derived4 &d) { return d; }
196 Public test2(Derived4 &d) { return d; }
197}
John McCallb0207482010-03-16 06:11:48 +0000198
199// Implicit copy assignment operator uses.
200namespace test5 {
201 class A {
202 void operator=(const A &); // expected-note 2 {{declared private here}}
203 };
204
205 class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}}
206 void test1() {
207 Test1 a;
208 a = Test1();
209 }
210
211 class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}}
212 void test2() {
213 Test2 a;
214 a = Test2();
215 }
216}
217
218// Implicit copy constructor uses.
219namespace test6 {
220 class A {
221 public: A();
222 private: A(const A &); // expected-note 2 {{declared private here}}
223 };
224
225 class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
226 void test1(const Test1 &t) {
227 Test1 a = t;
228 }
229
230 class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
231 void test2(const Test2 &t) {
232 Test2 a = t;
233 }
234}
John McCall10f28732010-03-18 06:42:38 +0000235
236// Redeclaration lookups are not accesses.
237namespace test7 {
238 class A {
239 int private_member;
240 };
241 class B : A {
242 int foo(int private_member) {
243 return 0;
244 }
245 };
246}
John McCall90c8c572010-03-18 08:19:33 +0000247
248// Ignored operator new and delete overloads are not
249namespace test8 {
250 typedef __typeof__(sizeof(int)) size_t;
251
252 class A {
253 void *operator new(size_t s);
254 void operator delete(void *p);
255 public:
256 void *operator new(size_t s, int n);
257 void operator delete(void *p, int n);
258 };
259
260 void test() {
261 new (2) A();
262 }
263}
John McCall7aceaf82010-03-18 23:49:19 +0000264
265// Don't silently upgrade forbidden-access paths to private.
266namespace test9 {
267 class A {
268 public: static int x;
269 };
270 class B : private A { // expected-note {{constrained by private inheritance here}}
271 };
272 class C : public B {
273 static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
274 };
275}
John McCallc1b621d2010-03-24 09:04:37 +0000276
277namespace test10 {
278 class A {
279 enum {
280 value = 10 // expected-note {{declared private here}}
281 };
282 friend class C;
283 };
284
285 class B {
286 enum {
287 value = A::value // expected-error {{'value' is a private member of 'test10::A'}}
288 };
289 };
290
291 class C {
292 enum {
293 value = A::value
294 };
295 };
296}
John McCall90f97892010-03-25 22:08:03 +0000297
298namespace test11 {
299 class A {
300 protected: virtual ~A();
301 };
302
303 class B : public A {
304 ~B();
305 };
306
307 B::~B() {};
308}
John McCall2cc26752010-03-27 06:55:49 +0000309
310namespace test12 {
311 class A {
312 int x;
313
314 void foo() {
315 class Local {
316 int foo(A *a) {
317 return a->x;
318 }
319 };
320 }
321 };
322}
John McCall6bb80172010-03-30 21:47:33 +0000323
324namespace test13 {
325 struct A {
326 int x;
327 unsigned foo() const;
328 };
329
330 struct B : protected A {
331 using A::foo;
332 using A::x;
333 };
334
335 void test() {
336 A *d;
337 d->foo();
338 (void) d->x;
339 }
340}
John McCallc91cc662010-04-07 00:41:46 +0000341
342// Destructors for temporaries.
343namespace test14 {
344 class A {
345 private: ~A(); // expected-note {{declared private here}}
346 };
347 A foo();
348
349 void test() {
350 foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
351 }
352}