1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++98 %s |
2 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s |
3 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s |
4 | |
5 | // C++0x [class.access]p4: |
6 | |
7 | // Access control is applied uniformly to all names, whether the |
8 | // names are referred to from declarations or expressions. In the |
9 | // case of overloaded function names, access control is applied to |
10 | // the function selected by overload resolution. |
11 | |
12 | class Public {} PublicInst; |
13 | class Protected {} ProtectedInst; |
14 | class Private {} PrivateInst; |
15 | |
16 | namespace test0 { |
17 | class A { |
18 | public: |
19 | void foo(Public&); |
20 | protected: |
21 | void foo(Protected&); // expected-note 2 {{declared protected here}} |
22 | private: |
23 | void foo(Private&); // expected-note 2 {{declared private here}} |
24 | }; |
25 | |
26 | void test(A *op) { |
27 | op->foo(PublicInst); |
28 | op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}} |
29 | op->foo(PrivateInst); // expected-error {{'foo' is a private member}} |
30 | |
31 | void (A::*a)(Public&) = &A::foo; |
32 | void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}} |
33 | void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}} |
34 | } |
35 | } |
36 | |
37 | // Member operators. |
38 | namespace test1 { |
39 | class A { |
40 | public: |
41 | void operator+(Public&); |
42 | void operator[](Public&); |
43 | void operator()(Public&); |
44 | typedef void (*PublicSurrogate)(Public&); |
45 | operator PublicSurrogate() const; |
46 | protected: |
47 | void operator+(Protected&); // expected-note {{declared protected here}} |
48 | void operator[](Protected&); // expected-note {{declared protected here}} |
49 | void operator()(Protected&); // expected-note {{declared protected here}} |
50 | typedef void (*ProtectedSurrogate)(Protected&); |
51 | operator ProtectedSurrogate() const; // expected-note {{declared protected here}} |
52 | private: |
53 | void operator+(Private&); // expected-note {{declared private here}} |
54 | void operator[](Private&); // expected-note {{declared private here}} |
55 | void operator()(Private&); // expected-note {{declared private here}} |
56 | void operator-(); // expected-note {{declared private here}} |
57 | typedef void (*PrivateSurrogate)(Private&); |
58 | operator PrivateSurrogate() const; // expected-note {{declared private here}} |
59 | }; |
60 | void operator+(const A &, Public&); |
61 | void operator+(const A &, Protected&); |
62 | void operator+(const A &, Private&); |
63 | void operator-(const A &); |
64 | |
65 | void test(A &a, Public &pub, Protected &prot, Private &priv) { |
66 | a + pub; |
67 | a + prot; // expected-error {{'operator+' is a protected member}} |
68 | a + priv; // expected-error {{'operator+' is a private member}} |
69 | a[pub]; |
70 | a[prot]; // expected-error {{'operator[]' is a protected member}} |
71 | a[priv]; // expected-error {{'operator[]' is a private member}} |
72 | a(pub); |
73 | a(prot); // expected-error {{'operator()' is a protected member}} |
74 | a(priv); // expected-error {{'operator()' is a private member}} |
75 | -a; // expected-error {{'operator-' is a private member}} |
76 | |
77 | const A &ca = a; |
78 | ca + pub; |
79 | ca + prot; |
80 | ca + priv; |
81 | -ca; |
82 | // These are all surrogate calls |
83 | ca(pub); |
84 | ca(prot); // expected-error {{'operator void (*)(Protected &)' is a protected member}} |
85 | ca(priv); // expected-error {{'operator void (*)(Private &)' is a private member}} |
86 | } |
87 | } |
88 | |
89 | // Implicit constructor calls. |
90 | namespace test2 { |
91 | class A { |
92 | private: |
93 | A(); // expected-note 1+{{declared private here}} |
94 | |
95 | static A foo; |
96 | }; |
97 | |
98 | A a; // expected-error {{calling a private constructor}} |
99 | A A::foo; // okay |
100 | |
101 | #if __cplusplus < 201103L |
102 | class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}} |
103 | B b; // expected-note{{implicit default constructor}} |
104 | |
105 | class C : virtual A { |
106 | public: |
107 | C(); |
108 | }; |
109 | |
110 | class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}} |
111 | D d; // expected-note{{implicit default constructor}} |
112 | #else |
113 | class B : A { }; // expected-note {{base class 'test2::A' has an inaccessible default constructor}} |
114 | B b; // expected-error {{call to implicitly-deleted default constructor}} |
115 | |
116 | // FIXME: Do a better job of explaining how we get here from class D. |
117 | class C : virtual A { // expected-note {{default constructor of 'D' is implicitly deleted because base class 'test2::A' has an inaccessible default constructor}} |
118 | public: |
119 | C(); |
120 | }; |
121 | |
122 | class D : C { }; |
123 | D d; // expected-error {{call to implicitly-deleted default constructor}} |
124 | #endif |
125 | } |
126 | |
127 | // Implicit destructor calls. |
128 | namespace test3 { |
129 | class A { |
130 | private: |
131 | ~A(); // expected-note 2 {{declared private here}} |
132 | static A foo; |
133 | }; |
134 | |
135 | A a; // expected-error {{variable of type 'test3::A' has private destructor}} |
136 | A A::foo; |
137 | |
138 | void foo(A param) { // okay |
139 | A local; // expected-error {{variable of type 'test3::A' has private destructor}} |
140 | } |
141 | |
142 | #if __cplusplus < 201103L |
143 | template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}} |
144 | class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \ |
145 | // expected-error {{base class 'Base<2>' has private destructor}} |
146 | class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}} |
147 | |
148 | // These don't cause diagnostics because we don't need the destructor. |
149 | class Derived0 : Base<0> { ~Derived0(); }; |
150 | class Derived1 : Base<1> { }; |
151 | |
152 | class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ |
153 | // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} |
154 | Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} |
155 | virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} |
156 | Base2, // expected-error {{base class 'test3::Base2' has private destructor}} |
157 | virtual Base3 |
158 | { |
159 | ~Derived2() {} |
160 | }; |
161 | |
162 | class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \ |
163 | // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}} \ |
164 | // expected-note 2{{implicit default constructor}} |
165 | Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}} |
166 | virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}} |
167 | Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}} |
168 | virtual Base3 |
169 | {}; |
170 | Derived3 d3; // expected-note 3{{implicit default constructor}}\ |
171 | // expected-note{{implicit destructor}}} |
172 | #else |
173 | template <unsigned N> class Base { ~Base(); }; // expected-note 4{{declared private here}} |
174 | class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 1{{declared private here}} |
175 | class Base3 : virtual Base<3> { public: ~Base3(); }; |
176 | |
177 | // These don't cause diagnostics because we don't need the destructor. |
178 | class Derived0 : Base<0> { ~Derived0(); }; |
179 | class Derived1 : Base<1> { }; |
180 | |
181 | class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ |
182 | // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} |
183 | Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} |
184 | virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} |
185 | Base2, // expected-error {{base class 'test3::Base2' has private destructor}} |
186 | virtual Base3 |
187 | { |
188 | ~Derived2() {} |
189 | }; |
190 | |
191 | class Derived3 : |
192 | Base<0>, // expected-note {{deleted because base class 'Base<0>' has an inaccessible destructor}} |
193 | virtual Base<1>, |
194 | Base2, |
195 | virtual Base3 |
196 | {}; |
197 | Derived3 d3; // expected-error {{implicitly-deleted default constructor}} |
198 | #endif |
199 | } |
200 | |
201 | // Conversion functions. |
202 | namespace test4 { |
203 | class Base { |
204 | private: |
205 | operator Private(); // expected-note 4 {{declared private here}} |
206 | public: |
207 | operator Public(); // expected-note 2{{member is declared here}} |
208 | }; |
209 | |
210 | class Derived1 : private Base { // expected-note 2 {{declared private here}} \ |
211 | // expected-note {{constrained by private inheritance}} |
212 | Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} |
213 | Public test2() { return *this; } |
214 | }; |
215 | Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \ |
216 | // expected-error {{cannot cast 'test4::Derived1' to its private base class}} |
217 | Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \ |
218 | // expected-error {{'operator Public' is a private member}} |
219 | |
220 | |
221 | class Derived2 : public Base { |
222 | Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} |
223 | Public test2() { return *this; } |
224 | }; |
225 | Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}} |
226 | Public test2(Derived2 &d) { return d; } |
227 | |
228 | class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \ |
229 | // expected-note {{declared private here}} |
230 | public: |
231 | operator Private(); |
232 | }; |
233 | Private test1(Derived3 &d) { return d; } |
234 | Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \ |
235 | // expected-error {{cannot cast 'test4::Derived3' to its private base class}} |
236 | |
237 | class Derived4 : public Base { |
238 | public: |
239 | operator Private(); |
240 | }; |
241 | Private test1(Derived4 &d) { return d; } |
242 | Public test2(Derived4 &d) { return d; } |
243 | } |
244 | |
245 | // Implicit copy assignment operator uses. |
246 | namespace test5 { |
247 | class A { |
248 | void operator=(const A &); |
249 | #if __cplusplus < 201103L |
250 | // expected-note@-2 2{{implicitly declared private here}} |
251 | #endif |
252 | }; |
253 | |
254 | #if __cplusplus < 201103L |
255 | class Test1 { A a; }; // expected-error {{private member}} |
256 | void test1() { |
257 | Test1 a; |
258 | a = Test1(); // expected-note{{implicit copy}} |
259 | } |
260 | |
261 | class Test2 : A {}; // expected-error {{private member}} |
262 | void test2() { |
263 | Test2 a; |
264 | a = Test2(); // expected-note{{implicit copy}} |
265 | } |
266 | #else |
267 | class Test1 { A a; }; // expected-note {{because field 'a' has an inaccessible copy assignment operator}} |
268 | void test1() { |
269 | Test1 a; |
270 | a = Test1(); // expected-error {{copy assignment operator is implicitly deleted}} |
271 | } |
272 | |
273 | class Test2 : A {}; // expected-note {{because base class 'test5::A' has an inaccessible copy assignment operator}} |
274 | void test2() { |
275 | Test2 a; |
276 | a = Test2(); // expected-error {{copy assignment operator is implicitly deleted}} |
277 | } |
278 | #endif |
279 | } |
280 | |
281 | // Implicit copy constructor uses. |
282 | namespace test6 { |
283 | class A { |
284 | public: A(); |
285 | private: A(const A &); |
286 | #if __cplusplus < 201103L |
287 | // expected-note@-2 2{{declared private here}} |
288 | #endif |
289 | }; |
290 | |
291 | #if __cplusplus < 201103L |
292 | class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}} |
293 | void test1(const Test1 &t) { |
294 | Test1 a = t; // expected-note{{implicit copy}} |
295 | } |
296 | |
297 | class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}} |
298 | void test2(const Test2 &t) { |
299 | Test2 a = t; // expected-note{{implicit copy}} |
300 | } |
301 | #else |
302 | class Test1 { A a; }; // expected-note {{field 'a' has an inaccessible copy constructor}} |
303 | void test1(const Test1 &t) { |
304 | Test1 a = t; // expected-error{{implicitly-deleted}} |
305 | } |
306 | |
307 | class Test2 : A {}; // expected-note {{base class 'test6::A' has an inaccessible copy constructor}} |
308 | void test2(const Test2 &t) { |
309 | Test2 a = t; // expected-error{{implicitly-deleted}} |
310 | } |
311 | #endif |
312 | } |
313 | |
314 | // Redeclaration lookups are not accesses. |
315 | namespace test7 { |
316 | class A { |
317 | int private_member; |
318 | }; |
319 | class B : A { |
320 | int foo(int private_member) { |
321 | return 0; |
322 | } |
323 | }; |
324 | } |
325 | |
326 | // Ignored operator new and delete overloads are not |
327 | namespace test8 { |
328 | typedef __typeof__(sizeof(int)) size_t; |
329 | |
330 | class A { |
331 | void *operator new(size_t s); |
332 | void operator delete(void *p); |
333 | public: |
334 | void *operator new(size_t s, int n); |
335 | void operator delete(void *p, int n); |
336 | }; |
337 | |
338 | void test() { |
339 | new (2) A(); |
340 | } |
341 | } |
342 | |
343 | // Don't silently upgrade forbidden-access paths to private. |
344 | namespace test9 { |
345 | class A { |
346 | public: static int x; // expected-note {{member is declared here}} |
347 | }; |
348 | class B : private A { // expected-note {{constrained by private inheritance here}} |
349 | }; |
350 | class C : public B { |
351 | static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}} |
352 | }; |
353 | } |
354 | |
355 | namespace test10 { |
356 | class A { |
357 | enum { |
358 | value = 10 // expected-note {{declared private here}} |
359 | }; |
360 | friend class C; |
361 | }; |
362 | |
363 | class B { |
364 | enum { |
365 | value = A::value // expected-error {{'value' is a private member of 'test10::A'}} |
366 | }; |
367 | }; |
368 | |
369 | class C { |
370 | enum { |
371 | value = A::value |
372 | }; |
373 | }; |
374 | } |
375 | |
376 | namespace test11 { |
377 | class A { |
378 | protected: virtual ~A(); |
379 | }; |
380 | |
381 | class B : public A { |
382 | ~B(); |
383 | }; |
384 | |
385 | B::~B() {}; |
386 | } |
387 | |
388 | namespace test12 { |
389 | class A { |
390 | int x; |
391 | |
392 | void foo() { |
393 | class Local { |
394 | int foo(A *a) { |
395 | return a->x; |
396 | } |
397 | }; |
398 | } |
399 | }; |
400 | } |
401 | |
402 | namespace test13 { |
403 | struct A { |
404 | int x; |
405 | unsigned foo() const; |
406 | }; |
407 | |
408 | struct B : protected A { |
409 | using A::foo; |
410 | using A::x; |
411 | }; |
412 | |
413 | void test() { |
414 | A *d; |
415 | d->foo(); |
416 | (void) d->x; |
417 | } |
418 | } |
419 | |
420 | // Destructors for temporaries. |
421 | namespace test14 { |
422 | class A { |
423 | private: ~A(); // expected-note {{declared private here}} |
424 | }; |
425 | A foo(); |
426 | |
427 | void test() { |
428 | foo(); // expected-error {{temporary of type 'test14::A' has private destructor}} |
429 | } |
430 | |
431 | class X { |
432 | ~X(); // expected-note {{declared private here}} |
433 | }; |
434 | |
435 | struct Y1 { |
436 | operator X(); |
437 | }; |
438 | |
439 | void g() { |
440 | const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}} |
441 | } |
442 | } |
443 | |
444 | // PR 7024 |
445 | namespace test15 { |
446 | template <class T> class A { |
447 | private: |
448 | int private_foo; // expected-note {{declared private here}} |
449 | static int private_sfoo; // expected-note {{declared private here}} |
450 | protected: |
451 | int protected_foo; // expected-note 3 {{declared protected here}} // expected-note {{can only access this member on an object of type 'test15::B<int>'}} |
452 | static int protected_sfoo; // expected-note 3 {{declared protected here}} |
453 | |
454 | int test1(A<int> &a) { |
455 | return a.private_foo; // expected-error {{private member}} |
456 | } |
457 | |
458 | int test2(A<int> &a) { |
459 | return a.private_sfoo; // expected-error {{private member}} |
460 | } |
461 | |
462 | int test3(A<int> &a) { |
463 | return a.protected_foo; // expected-error {{protected member}} |
464 | } |
465 | |
466 | int test4(A<int> &a) { |
467 | return a.protected_sfoo; // expected-error {{protected member}} |
468 | } |
469 | }; |
470 | |
471 | template class A<int>; |
472 | template class A<long>; // expected-note 4 {{in instantiation}} |
473 | |
474 | template <class T> class B : public A<T> { |
475 | // TODO: These first two accesses can be detected as ill-formed at |
476 | // definition time because they're member accesses and A<int> can't |
477 | // be a subclass of B<T> for any T. |
478 | |
479 | int test1(A<int> &a) { |
480 | return a.protected_foo; // expected-error 2 {{protected member}} |
481 | } |
482 | |
483 | int test2(A<int> &a) { |
484 | return a.protected_sfoo; // expected-error {{protected member}} |
485 | } |
486 | |
487 | int test3(B<int> &b) { |
488 | return b.protected_foo; // expected-error {{protected member}} |
489 | } |
490 | |
491 | int test4(B<int> &b) { |
492 | return b.protected_sfoo; // expected-error {{protected member}} |
493 | } |
494 | }; |
495 | |
496 | template class B<int>; // expected-note {{in instantiation}} |
497 | template class B<long>; // expected-note 4 {{in instantiation}} |
498 | } |
499 | |
500 | // PR7281 |
501 | namespace test16 { |
502 | class A { ~A(); }; // expected-note 2{{declared private here}} |
503 | void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \ |
504 | // expected-error{{exception object of type 'test16::A' has private destructor}} |
505 | } |
506 | |
507 | // rdar://problem/8146294 |
508 | namespace test17 { |
509 | class A { |
510 | template <typename T> class Inner { }; // expected-note {{declared private here}} |
511 | }; |
512 | |
513 | A::Inner<int> s; // expected-error {{'Inner' is a private member of 'test17::A'}} |
514 | } |
515 | |
516 | namespace test18 { |
517 | template <class T> class A {}; // expected-note {{member is declared here}} |
518 | class B : A<int> { // expected-note {{constrained by implicitly private inheritance here}} |
519 | A<int> member; |
520 | }; |
521 | class C : B { |
522 | A<int> member; // expected-error {{'A' is a private member of 'test18::A<int>'}} |
523 | }; |
524 | } |
525 | |
526 | // PR8325 |
527 | namespace test19 { |
528 | class A { ~A(); }; |
529 | // The destructor is not implicitly referenced here. Contrast to test16, |
530 | // testing PR7281, earlier in this file. |
531 | void b(A* x) { throw x; } |
532 | } |
533 | |
534 | // PR7930 |
535 | namespace test20 { |
536 | class Foo { |
537 | Foo(); // expected-note {{implicitly declared private here}} |
538 | }; |
539 | Foo::Foo() {} |
540 | |
541 | void test() { |
542 | Foo a; // expected-error {{calling a private constructor}} |
543 | } |
544 | } |
545 | |
546 | namespace test21 { |
547 | template <class T> class A { |
548 | void foo(); |
549 | void bar(); |
550 | class Inner; // expected-note {{implicitly declared private here}} |
551 | public: |
552 | void baz(); |
553 | }; |
554 | template <class T> class A<T>::Inner {}; |
555 | class B { |
556 | template <class T> class A<T>::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}} |
557 | }; |
558 | |
559 | void test() { |
560 | A<int>::Inner i; // expected-error {{'Inner' is a private member}} |
561 | } |
562 | } |
563 | |
564 | namespace rdar8876150 { |
565 | struct A { operator bool(); }; |
566 | struct B : private A { using A::operator bool; }; |
567 | |
568 | bool f() { |
569 | B b; |
570 | return !b; |
571 | } |
572 | } |
573 | |
574 | namespace test23 { |
575 | template <typename T> class A { |
576 | A(); |
577 | static A instance; |
578 | }; |
579 | |
580 | template <typename T> A<T> A<T>::instance; |
581 | template class A<int>; |
582 | } |
583 | |