• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
2 
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 
10 class Public {} PublicInst;
11 class Protected {} ProtectedInst;
12 class Private {} PrivateInst;
13 
14 namespace 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 
test(A * op)24   void test(A *op) {
25     op->foo(PublicInst);
26     op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}}
27     op->foo(PrivateInst); // expected-error {{'foo' is a private member}}
28 
29     void (A::*a)(Public&) = &A::foo;
30     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}}
32   }
33 }
34 
35 // Member operators.
36 namespace test1 {
37   class A {
38   public:
39     void operator+(Public&);
40     void operator[](Public&);
41     void operator()(Public&);
42     typedef void (*PublicSurrogate)(Public&);
43     operator PublicSurrogate() const;
44   protected:
45     void operator+(Protected&); // expected-note {{declared protected here}}
46     void operator[](Protected&); // expected-note {{declared protected here}}
47     void operator()(Protected&); // expected-note {{declared protected here}}
48     typedef void (*ProtectedSurrogate)(Protected&);
49     operator ProtectedSurrogate() const; // expected-note {{declared protected here}}
50   private:
51     void operator+(Private&); // expected-note {{declared private here}}
52     void operator[](Private&); // expected-note {{declared private here}}
53     void operator()(Private&); // expected-note {{declared private here}}
54     void operator-(); // expected-note {{declared private here}}
55     typedef void (*PrivateSurrogate)(Private&);
56     operator PrivateSurrogate() const; // expected-note {{declared private here}}
57   };
58   void operator+(const A &, Public&);
59   void operator+(const A &, Protected&);
60   void operator+(const A &, Private&);
61   void operator-(const A &);
62 
test(A & a,Public & pub,Protected & prot,Private & priv)63   void test(A &a, Public &pub, Protected &prot, Private &priv) {
64     a + pub;
65     a + prot; // expected-error {{'operator+' is a protected member}}
66     a + priv; // expected-error {{'operator+' is a private member}}
67     a[pub];
68     a[prot]; // expected-error {{'operator[]' is a protected member}}
69     a[priv]; // expected-error {{'operator[]' is a private member}}
70     a(pub);
71     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}}
74 
75     const A &ca = a;
76     ca + pub;
77     ca + prot;
78     ca + priv;
79     -ca;
80     // These are all surrogate calls
81     ca(pub);
82     ca(prot); // expected-error {{'operator void (*)(Protected &)' is a protected member}}
83     ca(priv); // expected-error {{'operator void (*)(Private &)' is a private member}}
84   }
85 }
86 
87 // Implicit constructor calls.
88 namespace test2 {
89   class A {
90   private:
91     A(); // expected-note 3 {{declared private here}}
92 
93     static A foo;
94   };
95 
96   A a; // expected-error {{calling a private constructor}}
97   A A::foo; // okay
98 
99   class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}}
100   B b; // expected-note{{implicit default constructor}}
101 
102   class C : virtual A {
103   public:
104     C();
105   };
106 
107   class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private default constructor}}
108   D d; // expected-note{{implicit default constructor}}
109 }
110 
111 // Implicit destructor calls.
112 namespace test3 {
113   class A {
114   private:
115     ~A(); // expected-note 2 {{declared private here}}
116     static A foo;
117   };
118 
119   A a; // expected-error {{variable of type 'test3::A' has private destructor}}
120   A A::foo;
121 
foo(A param)122   void foo(A param) { // okay
123     A local; // expected-error {{variable of type 'test3::A' has private destructor}}
124   }
125 
126   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}}
130 
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   {
~Derived2()142     ~Derived2() {}
143   };
144 
145   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     // expected-note 2{{implicit default constructor}}
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}}
151     virtual Base3
152   {};
153   Derived3 d3; // expected-note {{implicit default constructor}}\
154                // expected-note{{implicit destructor}}}
155 }
156 
157 // Conversion functions.
158 namespace test4 {
159   class Base {
160   private:
161     operator Private(); // expected-note 4 {{declared private here}}
162   public:
163     operator Public(); // expected-note 2{{member is declared here}}
164   };
165 
166   class Derived1 : private Base { // expected-note 2 {{declared private here}} \
167                                   // expected-note {{constrained by private inheritance}}
test1()168     Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
test2()169     Public test2() { return *this; }
170   };
test1(Derived1 & d)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}}
test2(Derived1 & d)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 {
test1()178     Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
test2()179     Public test2() { return *this; }
180   };
test1(Derived2 & d)181   Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
test2(Derived2 & d)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   };
test1(Derived3 & d)189   Private test1(Derived3 &d) { return d; }
test2(Derived3 & 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   };
test1(Derived4 & d)197   Private test1(Derived4 &d) { return d; }
test2(Derived4 & d)198   Public test2(Derived4 &d) { return d; }
199 }
200 
201 // Implicit copy assignment operator uses.
202 namespace test5 {
203   class A {
204     void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
205   };
206 
207   class Test1 { A a; }; // expected-error {{private member}}
test1()208   void test1() {
209     Test1 a;
210     a = Test1(); // expected-note{{implicit copy}}
211   }
212 
213   class Test2 : A {}; // expected-error {{private member}}
test2()214   void test2() {
215     Test2 a;
216     a = Test2(); // expected-note{{implicit copy}}
217   }
218 }
219 
220 // Implicit copy constructor uses.
221 namespace test6 {
222   class A {
223     public: A();
224     private: A(const A &); // expected-note 2 {{declared private here}}
225   };
226 
227   class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
test1(const Test1 & t)228   void test1(const Test1 &t) {
229     Test1 a = t; // expected-note{{implicit copy}}
230   }
231 
232   class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
test2(const Test2 & t)233   void test2(const Test2 &t) {
234     Test2 a = t; // expected-note{{implicit copy}}
235   }
236 }
237 
238 // Redeclaration lookups are not accesses.
239 namespace test7 {
240   class A {
241     int private_member;
242   };
243   class B : A {
foo(int private_member)244     int foo(int private_member) {
245       return 0;
246     }
247   };
248 }
249 
250 // Ignored operator new and delete overloads are not
251 namespace 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 
test()262   void test() {
263     new (2) A();
264   }
265 }
266 
267 // Don't silently upgrade forbidden-access paths to private.
268 namespace test9 {
269   class A {
270   public: static int x; // expected-note {{member is declared here}}
271   };
272   class B : private A { // expected-note {{constrained by private inheritance here}}
273   };
274   class C : public B {
getX()275     static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
276   };
277 }
278 
279 namespace 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 }
299 
300 namespace test11 {
301   class A {
302     protected: virtual ~A();
303   };
304 
305   class B : public A {
306     ~B();
307   };
308 
~B()309   B::~B() {};
310 }
311 
312 namespace test12 {
313   class A {
314     int x;
315 
foo()316     void foo() {
317       class Local {
318         int foo(A *a) {
319           return a->x;
320         }
321       };
322     }
323   };
324 }
325 
326 namespace 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 
test()337   void test() {
338     A *d;
339     d->foo();
340     (void) d->x;
341   }
342 }
343 
344 // Destructors for temporaries.
345 namespace test14 {
346   class A {
347   private: ~A(); // expected-note {{declared private here}}
348   };
349   A foo();
350 
test()351   void test() {
352     foo(); // expected-error {{temporary of type 'test14::A' has private destructor}}
353   }
354 
355   class X {
356     ~X(); // expected-note {{declared private here}}
357   };
358 
359   struct Y1 {
360     operator X();
361   };
362 
g()363   void g() {
364     const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}}
365   }
366 }
367 
368 // PR 7024
369 namespace 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:
375     int protected_foo; // expected-note 3 {{declared protected here}} // expected-note {{can only access this member on an object of type 'test15::B<int>'}}
376     static int protected_sfoo; // expected-note 3 {{declared protected here}}
377 
test1(A<int> & a)378     int test1(A<int> &a) {
379       return a.private_foo; // expected-error {{private member}}
380     }
381 
test2(A<int> & a)382     int test2(A<int> &a) {
383       return a.private_sfoo; // expected-error {{private member}}
384     }
385 
test3(A<int> & a)386     int test3(A<int> &a) {
387       return a.protected_foo; // expected-error {{protected member}}
388     }
389 
test4(A<int> & a)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 
test1(A<int> & a)403     int test1(A<int> &a) {
404       return a.protected_foo; // expected-error 2 {{protected member}}
405     }
406 
test2(A<int> & a)407     int test2(A<int> &a) {
408       return a.protected_sfoo; // expected-error {{protected member}}
409     }
410 
test3(B<int> & b)411     int test3(B<int> &b) {
412       return b.protected_foo; // expected-error {{protected member}}
413     }
414 
test4(B<int> & b)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 }
423 
424 // PR7281
425 namespace test16 {
426   class A { ~A(); }; // expected-note 2{{declared private here}}
b()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}}
429 }
430 
431 // rdar://problem/8146294
432 namespace 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 }
439 
440 namespace 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 }
453 
454 // PR8325
455 namespace test19 {
456   class A { ~A(); };
457   // The destructor is not implicitly referenced here.  Contrast to test16,
458   // testing PR7281, earlier in this file.
b(A * x)459   void b(A* x) { throw x; }
460 }
461 
462 // PR7930
463 namespace test20 {
464   class Foo {
465     Foo(); // expected-note {{implicitly declared private here}}
466   };
Foo()467   Foo::Foo() {}
468 
test()469   void test() {
470     Foo a; // expected-error {{calling a private constructor}}
471   }
472 }
473 
474 namespace 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 {
484     template <class T> class A<T>::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}}
485   };
486 
test()487   void test() {
488     A<int>::Inner i; // expected-error {{'Inner' is a private member}}
489   }
490 }
491 
492 namespace rdar8876150 {
493   struct A { operator bool(); };
494   struct B : private A { using A::operator bool; };
495 
f()496   bool f() {
497     B b;
498     return !b;
499   }
500 }
501 
502 namespace 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 }
511