blob: 3d1578a4fc8397633e73c816a3c2b4d4307897d7 [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 };
106
107 // FIXME: It would be better if this said something about A being an inherited virtual base.
108 class D : C { }; // expected-error {{base class 'test2::A' has private constructor}}
109 D d;
John McCall4f9506a2010-02-02 08:45:54 +0000110}
111
112// Implicit destructor calls.
113namespace test3 {
John McCall58e6f342010-03-16 05:22:47 +0000114 class A {
John McCall4f9506a2010-02-02 08:45:54 +0000115 private:
Douglas Gregor9c127392010-03-26 06:57:13 +0000116 ~A(); // expected-note 2 {{declared private here}}
John McCall4f9506a2010-02-02 08:45:54 +0000117 static A foo;
118 };
119
John McCall58e6f342010-03-16 05:22:47 +0000120 A a; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000121 A A::foo;
122
Douglas Gregor9c127392010-03-26 06:57:13 +0000123 void foo(A param) { // okay
John McCall58e6f342010-03-16 05:22:47 +0000124 A local; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000125 }
John McCall58e6f342010-03-16 05:22:47 +0000126
John McCallef027fe2010-03-16 21:39:52 +0000127 template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
128 class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
129 // expected-error {{base class 'Base<2>' has private destructor}}
130 class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
John McCall58e6f342010-03-16 05:22:47 +0000131
132 // These don't cause diagnostics because we don't need the destructor.
133 class Derived0 : Base<0> { ~Derived0(); };
134 class Derived1 : Base<1> { };
135
136 class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
137 // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
138 Base<0>, // expected-error {{base class 'Base<0>' has private destructor}}
139 virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
140 Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
141 virtual Base3
142 {
143 ~Derived2() {}
144 };
John McCall6c790ea2010-03-16 05:36:30 +0000145
John McCallef027fe2010-03-16 21:39:52 +0000146 class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
147 // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}}
148 Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}}
149 virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
150 Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
John McCall6c790ea2010-03-16 05:36:30 +0000151 virtual Base3
152 {};
153 Derived3 d3;
John McCall4f9506a2010-02-02 08:45:54 +0000154}
John McCallb05b5f32010-03-15 09:07:48 +0000155
156// Conversion functions.
157namespace test4 {
158 class Base {
159 private:
160 operator Private(); // expected-note 4 {{declared private here}}
161 public:
162 operator Public();
163 };
164
165 class Derived1 : private Base { // expected-note 2 {{declared private here}} \
166 // expected-note {{constrained by private inheritance}}
167 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
168 Public test2() { return *this; }
169 };
170 Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
171 // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
172 Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
173 // expected-error {{'operator Public' is a private member}}
174
175
176 class Derived2 : public Base {
177 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
178 Public test2() { return *this; }
179 };
180 Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
181 Public test2(Derived2 &d) { return d; }
182
183 class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
184 // expected-note {{declared private here}}
185 public:
186 operator Private();
187 };
188 Private test1(Derived3 &d) { return d; }
189 Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
190 // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
191
192 class Derived4 : public Base {
193 public:
194 operator Private();
195 };
196 Private test1(Derived4 &d) { return d; }
197 Public test2(Derived4 &d) { return d; }
198}
John McCallb0207482010-03-16 06:11:48 +0000199
200// Implicit copy assignment operator uses.
201namespace test5 {
202 class A {
203 void operator=(const A &); // expected-note 2 {{declared private here}}
204 };
205
206 class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}}
207 void test1() {
208 Test1 a;
209 a = Test1();
210 }
211
212 class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}}
213 void test2() {
214 Test2 a;
215 a = Test2();
216 }
217}
218
219// Implicit copy constructor uses.
220namespace test6 {
221 class A {
222 public: A();
223 private: A(const A &); // expected-note 2 {{declared private here}}
224 };
225
226 class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
227 void test1(const Test1 &t) {
228 Test1 a = t;
229 }
230
231 class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
232 void test2(const Test2 &t) {
233 Test2 a = t;
234 }
235}
John McCall10f28732010-03-18 06:42:38 +0000236
237// Redeclaration lookups are not accesses.
238namespace test7 {
239 class A {
240 int private_member;
241 };
242 class B : A {
243 int foo(int private_member) {
244 return 0;
245 }
246 };
247}
John McCall90c8c572010-03-18 08:19:33 +0000248
249// Ignored operator new and delete overloads are not
250namespace test8 {
251 typedef __typeof__(sizeof(int)) size_t;
252
253 class A {
254 void *operator new(size_t s);
255 void operator delete(void *p);
256 public:
257 void *operator new(size_t s, int n);
258 void operator delete(void *p, int n);
259 };
260
261 void test() {
262 new (2) A();
263 }
264}
John McCall7aceaf82010-03-18 23:49:19 +0000265
266// Don't silently upgrade forbidden-access paths to private.
267namespace test9 {
268 class A {
269 public: static int x;
270 };
271 class B : private A { // expected-note {{constrained by private inheritance here}}
272 };
273 class C : public B {
274 static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
275 };
276}
John McCallc1b621d2010-03-24 09:04:37 +0000277
278namespace test10 {
279 class A {
280 enum {
281 value = 10 // expected-note {{declared private here}}
282 };
283 friend class C;
284 };
285
286 class B {
287 enum {
288 value = A::value // expected-error {{'value' is a private member of 'test10::A'}}
289 };
290 };
291
292 class C {
293 enum {
294 value = A::value
295 };
296 };
297}
John McCall90f97892010-03-25 22:08:03 +0000298
299namespace test11 {
300 class A {
301 protected: virtual ~A();
302 };
303
304 class B : public A {
305 ~B();
306 };
307
308 B::~B() {};
309}
John McCall2cc26752010-03-27 06:55:49 +0000310
311namespace test12 {
312 class A {
313 int x;
314
315 void foo() {
316 class Local {
317 int foo(A *a) {
318 return a->x;
319 }
320 };
321 }
322 };
323}
John McCall6bb80172010-03-30 21:47:33 +0000324
325namespace test13 {
326 struct A {
327 int x;
328 unsigned foo() const;
329 };
330
331 struct B : protected A {
332 using A::foo;
333 using A::x;
334 };
335
336 void test() {
337 A *d;
338 d->foo();
339 (void) d->x;
340 }
341}
John McCallc91cc662010-04-07 00:41:46 +0000342
343// Destructors for temporaries.
344namespace test14 {
345 class A {
346 private: ~A(); // expected-note {{declared private here}}
347 };
348 A foo();
349
350 void test() {
351 foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
352 }
353}