blob: 5ad738bebf9cc384ed45a84566e1c1deed2bb630 [file] [log] [blame]
Anders Carlssonabea9512011-02-28 00:40:07 +00001// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -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
Sean Hunt82713172011-05-25 23:16:36 +000099 class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}}
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000100 B b; // expected-note{{implicit default constructor}}
Anders Carlsson9a68a672010-04-21 18:47:17 +0000101
102 class C : virtual A {
103 public:
104 C();
105 };
Anders Carlsson711f34a2010-04-21 19:52:01 +0000106
Sean Hunt82713172011-05-25 23:16:36 +0000107 class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}}
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000108 D d; // expected-note{{implicit default constructor}}
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}} \
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000146 // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}} \
147 // expected-note 2{{implicit default constructor}}
John McCallef027fe2010-03-16 21:39:52 +0000148 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
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000152 {};
153 Derived3 d3; // expected-note {{implicit default constructor}}\
154 // expected-note{{implicit default destructor}}}
John McCall4f9506a2010-02-02 08:45:54 +0000155}
John McCallb05b5f32010-03-15 09:07:48 +0000156
157// Conversion functions.
158namespace test4 {
159 class Base {
160 private:
161 operator Private(); // expected-note 4 {{declared private here}}
162 public:
Douglas Gregor76ef6582010-05-28 04:34:55 +0000163 operator Public(); // expected-note 2{{member is declared here}}
John McCallb05b5f32010-03-15 09:07:48 +0000164 };
165
166 class Derived1 : private Base { // expected-note 2 {{declared private here}} \
167 // expected-note {{constrained by private inheritance}}
168 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
169 Public test2() { return *this; }
170 };
171 Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
172 // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
173 Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
174 // expected-error {{'operator Public' is a private member}}
175
176
177 class Derived2 : public Base {
178 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
179 Public test2() { return *this; }
180 };
181 Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
182 Public test2(Derived2 &d) { return d; }
183
184 class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
185 // expected-note {{declared private here}}
186 public:
187 operator Private();
188 };
189 Private test1(Derived3 &d) { return d; }
190 Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
191 // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
192
193 class Derived4 : public Base {
194 public:
195 operator Private();
196 };
197 Private test1(Derived4 &d) { return d; }
198 Public test2(Derived4 &d) { return d; }
199}
John McCallb0207482010-03-16 06:11:48 +0000200
201// Implicit copy assignment operator uses.
202namespace test5 {
203 class A {
John McCallaa56a662010-10-20 08:15:06 +0000204 void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
John McCallb0207482010-03-16 06:11:48 +0000205 };
206
Douglas Gregor06a9f362010-05-01 20:49:11 +0000207 class Test1 { A a; }; // expected-error {{private member}}
John McCallb0207482010-03-16 06:11:48 +0000208 void test1() {
Sean Huntf961ea52011-05-10 19:08:14 +0000209 Test1 a;
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000210 a = Test1(); // expected-note{{implicit default copy}}
John McCallb0207482010-03-16 06:11:48 +0000211 }
212
Douglas Gregor06a9f362010-05-01 20:49:11 +0000213 class Test2 : A {}; // expected-error {{private member}}
John McCallb0207482010-03-16 06:11:48 +0000214 void test2() {
215 Test2 a;
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000216 a = Test2(); // expected-note{{implicit default copy}}
John McCallb0207482010-03-16 06:11:48 +0000217 }
218}
219
220// Implicit copy constructor uses.
221namespace test6 {
222 class A {
223 public: A();
224 private: A(const A &); // expected-note 2 {{declared private here}}
225 };
226
Matt Beaumont-Gay1e55e912011-05-19 23:44:42 +0000227 class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
John McCallb0207482010-03-16 06:11:48 +0000228 void test1(const Test1 &t) {
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000229 Test1 a = t; // expected-note{{implicit default copy}}
John McCallb0207482010-03-16 06:11:48 +0000230 }
231
Matt Beaumont-Gay1e55e912011-05-19 23:44:42 +0000232 class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
John McCallb0207482010-03-16 06:11:48 +0000233 void test2(const Test2 &t) {
Douglas Gregorc63d2c82010-05-12 16:39:35 +0000234 Test2 a = t; // expected-note{{implicit default copy}}
John McCallb0207482010-03-16 06:11:48 +0000235 }
236}
John McCall10f28732010-03-18 06:42:38 +0000237
238// Redeclaration lookups are not accesses.
239namespace test7 {
240 class A {
241 int private_member;
242 };
243 class B : A {
244 int foo(int private_member) {
245 return 0;
246 }
247 };
248}
John McCall90c8c572010-03-18 08:19:33 +0000249
250// Ignored operator new and delete overloads are not
251namespace test8 {
252 typedef __typeof__(sizeof(int)) size_t;
253
254 class A {
255 void *operator new(size_t s);
256 void operator delete(void *p);
257 public:
258 void *operator new(size_t s, int n);
259 void operator delete(void *p, int n);
260 };
261
262 void test() {
263 new (2) A();
264 }
265}
John McCall7aceaf82010-03-18 23:49:19 +0000266
267// Don't silently upgrade forbidden-access paths to private.
268namespace test9 {
269 class A {
Douglas Gregor76ef6582010-05-28 04:34:55 +0000270 public: static int x; // expected-note {{member is declared here}}
John McCall7aceaf82010-03-18 23:49:19 +0000271 };
272 class B : private A { // expected-note {{constrained by private inheritance here}}
273 };
274 class C : public B {
275 static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
276 };
277}
John McCallc1b621d2010-03-24 09:04:37 +0000278
279namespace test10 {
280 class A {
281 enum {
282 value = 10 // expected-note {{declared private here}}
283 };
284 friend class C;
285 };
286
287 class B {
288 enum {
289 value = A::value // expected-error {{'value' is a private member of 'test10::A'}}
290 };
291 };
292
293 class C {
294 enum {
295 value = A::value
296 };
297 };
298}
John McCall90f97892010-03-25 22:08:03 +0000299
300namespace test11 {
301 class A {
302 protected: virtual ~A();
303 };
304
305 class B : public A {
306 ~B();
307 };
308
309 B::~B() {};
310}
John McCall2cc26752010-03-27 06:55:49 +0000311
312namespace test12 {
313 class A {
314 int x;
315
316 void foo() {
317 class Local {
318 int foo(A *a) {
319 return a->x;
320 }
321 };
322 }
323 };
324}
John McCall6bb80172010-03-30 21:47:33 +0000325
326namespace test13 {
327 struct A {
328 int x;
329 unsigned foo() const;
330 };
331
332 struct B : protected A {
333 using A::foo;
334 using A::x;
335 };
336
337 void test() {
338 A *d;
339 d->foo();
340 (void) d->x;
341 }
342}
John McCallc91cc662010-04-07 00:41:46 +0000343
344// Destructors for temporaries.
345namespace test14 {
346 class A {
347 private: ~A(); // expected-note {{declared private here}}
348 };
349 A foo();
350
351 void test() {
352 foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
353 }
Douglas Gregor4154e0b2010-04-24 23:45:46 +0000354
355 class X {
356 ~X(); // expected-note {{declared private here}}
357 };
358
359 struct Y1 {
360 operator X();
361 };
362
363 void g() {
364 const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}}
365 }
John McCallc91cc662010-04-07 00:41:46 +0000366}
Douglas Gregor4154e0b2010-04-24 23:45:46 +0000367
John McCall01ebd9d2010-05-04 05:11:27 +0000368// PR 7024
369namespace test15 {
370 template <class T> class A {
371 private:
372 int private_foo; // expected-note {{declared private here}}
373 static int private_sfoo; // expected-note {{declared private here}}
374 protected:
John McCallb9abd8722012-04-07 03:04:20 +0000375 int protected_foo; // expected-note 3 {{declared protected here}} // expected-note {{can only access this member on an object of type 'test15::B<int>'}}
John McCall01ebd9d2010-05-04 05:11:27 +0000376 static int protected_sfoo; // expected-note 3 {{declared protected here}}
377
378 int test1(A<int> &a) {
379 return a.private_foo; // expected-error {{private member}}
380 }
381
382 int test2(A<int> &a) {
383 return a.private_sfoo; // expected-error {{private member}}
384 }
385
386 int test3(A<int> &a) {
387 return a.protected_foo; // expected-error {{protected member}}
388 }
389
390 int test4(A<int> &a) {
391 return a.protected_sfoo; // expected-error {{protected member}}
392 }
393 };
394
395 template class A<int>;
396 template class A<long>; // expected-note 4 {{in instantiation}}
397
398 template <class T> class B : public A<T> {
399 // TODO: These first two accesses can be detected as ill-formed at
400 // definition time because they're member accesses and A<int> can't
401 // be a subclass of B<T> for any T.
402
403 int test1(A<int> &a) {
404 return a.protected_foo; // expected-error 2 {{protected member}}
405 }
406
407 int test2(A<int> &a) {
408 return a.protected_sfoo; // expected-error {{protected member}}
409 }
410
411 int test3(B<int> &b) {
412 return b.protected_foo; // expected-error {{protected member}}
413 }
414
415 int test4(B<int> &b) {
416 return b.protected_sfoo; // expected-error {{protected member}}
417 }
418 };
419
420 template class B<int>; // expected-note {{in instantiation}}
421 template class B<long>; // expected-note 4 {{in instantiation}}
422}
Eli Friedman5ed9b932010-06-03 20:39:03 +0000423
424// PR7281
425namespace test16 {
Douglas Gregored8abf12010-07-08 06:14:04 +0000426 class A { ~A(); }; // expected-note 2{{declared private here}}
427 void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \
428 // expected-error{{exception object of type 'test16::A' has private destructor}}
Eli Friedman5ed9b932010-06-03 20:39:03 +0000429}
John McCallb8592062010-08-13 02:23:42 +0000430
431// rdar://problem/8146294
432namespace test17 {
433 class A {
434 template <typename T> class Inner { }; // expected-note {{declared private here}}
435 };
436
437 A::Inner<int> s; // expected-error {{'Inner' is a private member of 'test17::A'}}
438}
John McCall8ba66912010-08-13 07:02:08 +0000439
440namespace test18 {
441 template <class T> class A {};
442 class B : A<int> {
443 A<int> member;
444 };
445
446 // FIXME: this access to A should be forbidden (because C++ is dumb),
447 // but LookupResult can't express the necessary information to do
448 // the check, so we aggressively suppress access control.
449 class C : B {
450 A<int> member;
451 };
452}
Eli Friedman98efb9f2010-10-12 20:32:36 +0000453
454// PR8325
455namespace test19 {
456 class A { ~A(); };
457 // The destructor is not implicitly referenced here. Contrast to test16,
458 // testing PR7281, earlier in this file.
459 void b(A* x) { throw x; }
460}
John McCallaa56a662010-10-20 08:15:06 +0000461
462// PR7930
463namespace test20 {
464 class Foo {
465 Foo(); // expected-note {{implicitly declared private here}}
466 };
467 Foo::Foo() {}
468
469 void test() {
470 Foo a; // expected-error {{calling a private constructor}}
471 }
472}
473
474namespace test21 {
475 template <class T> class A {
476 void foo();
477 void bar();
478 class Inner; // expected-note {{implicitly declared private here}}
479 public:
480 void baz();
481 };
482 template <class T> class A<T>::Inner {};
483 class B {
Douglas Gregor42acead2012-03-17 23:06:31 +0000484 template <class T> class A<T>::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}}
John McCallaa56a662010-10-20 08:15:06 +0000485 };
486
487 void test() {
488 A<int>::Inner i; // expected-error {{'Inner' is a private member}}
489 }
490}
Douglas Gregor83eecbe2011-01-20 01:32:05 +0000491
492namespace rdar8876150 {
493 struct A { operator bool(); };
494 struct B : private A { using A::operator bool; };
495
496 bool f() {
497 B b;
498 return !b;
499 }
500}
John McCallf5ba7e02011-02-14 20:37:25 +0000501
502namespace test23 {
503 template <typename T> class A {
504 A();
505 static A instance;
506 };
507
508 template <typename T> A<T> A<T>::instance;
509 template class A<int>;
510}