p4.cpp revision 6698be8a6930730df5e61c941197e72682196187
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
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);
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.
36namespace 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
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 (*)(class Protected &)' is a protected member}}
83    ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
84  }
85}
86
87// Implicit constructor calls.
88namespace 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.
112namespace 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
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  {
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.
158namespace 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}}
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}
200
201// Implicit copy assignment operator uses.
202namespace 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}}
208  void test1() {
209    Test1 a;
210    a = Test1(); // expected-note{{implicit copy}}
211  }
212
213  class Test2 : A {}; // expected-error {{private member}}
214  void test2() {
215    Test2 a;
216    a = Test2(); // expected-note{{implicit copy}}
217  }
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
227  class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
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}}
233  void test2(const Test2 &t) {
234    Test2 a = t; // expected-note{{implicit copy}}
235  }
236}
237
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}
249
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}
266
267// Don't silently upgrade forbidden-access paths to private.
268namespace 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 {
275    static int getX() { return x; } // expected-error {{'x' is a private member of 'test9::A'}}
276  };
277}
278
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}
299
300namespace test11 {
301  class A {
302    protected: virtual ~A();
303  };
304
305  class B : public A {
306    ~B();
307  };
308
309  B::~B() {};
310}
311
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}
325
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}
343
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  }
354
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  }
366}
367
368// 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:
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
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}
423
424// PR7281
425namespace test16 {
426  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}}
429}
430
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}
439
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}
453
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}
461
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 {
484    template <class T> class A<T>::Inner; // expected-error{{non-friend class member 'Inner' cannot have a qualified name}}
485  };
486
487  void test() {
488    A<int>::Inner i; // expected-error {{'Inner' is a private member}}
489  }
490}
491
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}
501
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}
511