blob: d6244aaea04fded6795f81c3f0f228ded9d8bad0 [file] [log] [blame]
John McCallc373d482010-01-27 01:50:18 +00001// RUN: %clang_cc1 -fsyntax-only -faccess-control -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);
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:
91 A(); // expected-note {{declared private here}}
92
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
98}
99
100// Implicit destructor calls.
101namespace test3 {
John McCall58e6f342010-03-16 05:22:47 +0000102 class A {
John McCall4f9506a2010-02-02 08:45:54 +0000103 private:
104 ~A(); // expected-note 3 {{declared private here}}
105 static A foo;
106 };
107
John McCall58e6f342010-03-16 05:22:47 +0000108 A a; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000109 A A::foo;
110
John McCall58e6f342010-03-16 05:22:47 +0000111 void foo(A param) { // expected-error {{variable of type 'test3::A' has private destructor}}
112 A local; // expected-error {{variable of type 'test3::A' has private destructor}}
John McCall4f9506a2010-02-02 08:45:54 +0000113 }
John McCall58e6f342010-03-16 05:22:47 +0000114
John McCallef027fe2010-03-16 21:39:52 +0000115 template <unsigned N> class Base { ~Base(); }; // expected-note 14 {{declared private here}}
116 class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 3 {{declared private here}} \
117 // expected-error {{base class 'Base<2>' has private destructor}}
118 class Base3 : virtual Base<3> { public: ~Base3(); }; // expected-error {{base class 'Base<3>' has private destructor}}
John McCall58e6f342010-03-16 05:22:47 +0000119
120 // These don't cause diagnostics because we don't need the destructor.
121 class Derived0 : Base<0> { ~Derived0(); };
122 class Derived1 : Base<1> { };
123
124 class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \
125 // expected-error {{inherited virtual base class 'Base<3>' has private destructor}}
126 Base<0>, // expected-error {{base class 'Base<0>' has private destructor}}
127 virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}}
128 Base2, // expected-error {{base class 'test3::Base2' has private destructor}}
129 virtual Base3
130 {
131 ~Derived2() {}
132 };
John McCall6c790ea2010-03-16 05:36:30 +0000133
John McCallef027fe2010-03-16 21:39:52 +0000134 class Derived3 : // expected-error 2 {{inherited virtual base class 'Base<2>' has private destructor}} \
135 // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}}
136 Base<0>, // expected-error 2 {{base class 'Base<0>' has private destructor}}
137 virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}}
138 Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}}
John McCall6c790ea2010-03-16 05:36:30 +0000139 virtual Base3
140 {};
141 Derived3 d3;
John McCall4f9506a2010-02-02 08:45:54 +0000142}
John McCallb05b5f32010-03-15 09:07:48 +0000143
144// Conversion functions.
145namespace test4 {
146 class Base {
147 private:
148 operator Private(); // expected-note 4 {{declared private here}}
149 public:
150 operator Public();
151 };
152
153 class Derived1 : private Base { // expected-note 2 {{declared private here}} \
154 // expected-note {{constrained by private inheritance}}
155 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
156 Public test2() { return *this; }
157 };
158 Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \
159 // expected-error {{cannot cast 'test4::Derived1' to its private base class}}
160 Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \
161 // expected-error {{'operator Public' is a private member}}
162
163
164 class Derived2 : public Base {
165 Private test1() { return *this; } // expected-error {{'operator Private' is a private member}}
166 Public test2() { return *this; }
167 };
168 Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}}
169 Public test2(Derived2 &d) { return d; }
170
171 class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \
172 // expected-note {{declared private here}}
173 public:
174 operator Private();
175 };
176 Private test1(Derived3 &d) { return d; }
177 Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \
178 // expected-error {{cannot cast 'test4::Derived3' to its private base class}}
179
180 class Derived4 : public Base {
181 public:
182 operator Private();
183 };
184 Private test1(Derived4 &d) { return d; }
185 Public test2(Derived4 &d) { return d; }
186}
John McCallb0207482010-03-16 06:11:48 +0000187
188// Implicit copy assignment operator uses.
189namespace test5 {
190 class A {
191 void operator=(const A &); // expected-note 2 {{declared private here}}
192 };
193
194 class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}}
195 void test1() {
196 Test1 a;
197 a = Test1();
198 }
199
200 class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}}
201 void test2() {
202 Test2 a;
203 a = Test2();
204 }
205}
206
207// Implicit copy constructor uses.
208namespace test6 {
209 class A {
210 public: A();
211 private: A(const A &); // expected-note 2 {{declared private here}}
212 };
213
214 class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
215 void test1(const Test1 &t) {
216 Test1 a = t;
217 }
218
219 class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
220 void test2(const Test2 &t) {
221 Test2 a = t;
222 }
223}
John McCall10f28732010-03-18 06:42:38 +0000224
225// Redeclaration lookups are not accesses.
226namespace test7 {
227 class A {
228 int private_member;
229 };
230 class B : A {
231 int foo(int private_member) {
232 return 0;
233 }
234 };
235}