1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | |
3 | namespace test0 { |
4 | class A { |
5 | protected: int x; // expected-note 3 {{declared}} \ |
6 | // expected-note {{member is declared here}} |
7 | static int sx; // expected-note 3 {{declared}} \ |
8 | // expected-note {{member is declared here}} |
9 | }; |
10 | class B : public A { |
11 | }; |
12 | class C : protected A { // expected-note {{declared}} |
13 | }; |
14 | class D : private B { // expected-note 3 {{constrained}} |
15 | }; |
16 | |
17 | void test(A &a) { |
18 | (void) a.x; // expected-error {{'x' is a protected member}} |
19 | (void) a.sx; // expected-error {{'sx' is a protected member}} |
20 | } |
21 | void test(B &b) { |
22 | (void) b.x; // expected-error {{'x' is a protected member}} |
23 | (void) b.sx; // expected-error {{'sx' is a protected member}} |
24 | } |
25 | void test(C &c) { |
26 | (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}} |
27 | (void) c.sx; // expected-error {{'sx' is a protected member}} |
28 | } |
29 | void test(D &d) { |
30 | (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}} |
31 | (void) d.sx; // expected-error {{'sx' is a private member}} |
32 | } |
33 | } |
34 | |
35 | namespace test1 { |
36 | class A { |
37 | protected: int x; |
38 | static int sx; |
39 | static void test(A&); |
40 | }; |
41 | class B : public A { |
42 | static void test(B&); |
43 | }; |
44 | class C : protected A { |
45 | static void test(C&); |
46 | }; |
47 | class D : private B { |
48 | static void test(D&); |
49 | }; |
50 | |
51 | void A::test(A &a) { |
52 | (void) a.x; |
53 | (void) a.sx; |
54 | } |
55 | void B::test(B &b) { |
56 | (void) b.x; |
57 | (void) b.sx; |
58 | } |
59 | void C::test(C &c) { |
60 | (void) c.x; |
61 | (void) c.sx; |
62 | } |
63 | void D::test(D &d) { |
64 | (void) d.x; |
65 | (void) d.sx; |
66 | } |
67 | } |
68 | |
69 | namespace test2 { |
70 | class A { |
71 | protected: int x; // expected-note 3 {{can only access this member on an object of type}} |
72 | static int sx; |
73 | static void test(A&); |
74 | }; |
75 | class B : public A { |
76 | static void test(A&); |
77 | }; |
78 | class C : protected A { |
79 | static void test(A&); |
80 | }; |
81 | class D : private B { |
82 | static void test(A&); |
83 | }; |
84 | |
85 | void A::test(A &a) { |
86 | (void) a.x; |
87 | (void) a.sx; |
88 | } |
89 | void B::test(A &a) { |
90 | (void) a.x; // expected-error {{'x' is a protected member}} |
91 | (void) a.sx; |
92 | } |
93 | void C::test(A &a) { |
94 | (void) a.x; // expected-error {{'x' is a protected member}} |
95 | (void) a.sx; |
96 | } |
97 | void D::test(A &a) { |
98 | (void) a.x; // expected-error {{'x' is a protected member}} |
99 | (void) a.sx; |
100 | } |
101 | } |
102 | |
103 | namespace test3 { |
104 | class B; |
105 | class A { |
106 | protected: int x; //expected-note {{declared protected}} // expected-note {{can only access this member on an object of type}} |
107 | static int sx; |
108 | static void test(B&); |
109 | }; |
110 | class B : public A { |
111 | static void test(B&); |
112 | }; |
113 | class C : protected A { |
114 | static void test(B&); |
115 | }; |
116 | class D : private B { |
117 | static void test(B&); |
118 | }; |
119 | |
120 | void A::test(B &b) { |
121 | (void) b.x; |
122 | (void) b.sx; |
123 | } |
124 | void B::test(B &b) { |
125 | (void) b.x; |
126 | (void) b.sx; |
127 | } |
128 | void C::test(B &b) { |
129 | (void) b.x; // expected-error {{'x' is a protected member}} |
130 | (void) b.sx; |
131 | } |
132 | void D::test(B &b) { |
133 | (void) b.x; // expected-error {{'x' is a protected member}} |
134 | (void) b.sx; |
135 | } |
136 | } |
137 | |
138 | namespace test4 { |
139 | class C; |
140 | class A { |
141 | protected: int x; // expected-note 2{{declared protected here}} expected-note{{member is declared here}} |
142 | static int sx; // expected-note 3{{member is declared here}} |
143 | static void test(C&); |
144 | }; |
145 | class B : public A { |
146 | static void test(C&); |
147 | }; |
148 | class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}} |
149 | static void test(C&); |
150 | }; |
151 | class D : private B { |
152 | static void test(C&); |
153 | }; |
154 | |
155 | void A::test(C &c) { |
156 | (void) c.x; // expected-error {{'x' is a protected member}} \ |
157 | // expected-error {{protected base class}} |
158 | (void) c.sx; // expected-error {{'sx' is a protected member}} |
159 | } |
160 | void B::test(C &c) { |
161 | (void) c.x; // expected-error {{'x' is a protected member}} \ |
162 | // expected-error {{protected base class}} |
163 | (void) c.sx; // expected-error {{'sx' is a protected member}} |
164 | } |
165 | void C::test(C &c) { |
166 | (void) c.x; |
167 | (void) c.sx; |
168 | } |
169 | void D::test(C &c) { |
170 | (void) c.x; // expected-error {{'x' is a protected member}} \ |
171 | // expected-error {{protected base class}} |
172 | (void) c.sx; // expected-error {{'sx' is a protected member}} |
173 | } |
174 | } |
175 | |
176 | namespace test5 { |
177 | class D; |
178 | class A { |
179 | protected: int x; // expected-note 3{{member is declared here}} |
180 | static int sx; // expected-note 3{{member is declared here}} |
181 | static void test(D&); |
182 | }; |
183 | class B : public A { |
184 | static void test(D&); |
185 | }; |
186 | class C : protected A { |
187 | static void test(D&); |
188 | }; |
189 | class D : private B { // expected-note 9 {{constrained}} |
190 | static void test(D&); |
191 | }; |
192 | |
193 | void A::test(D &d) { |
194 | (void) d.x; // expected-error {{'x' is a private member}} \ |
195 | // expected-error {{cannot cast}} |
196 | (void) d.sx; // expected-error {{'sx' is a private member}} |
197 | } |
198 | void B::test(D &d) { |
199 | (void) d.x; // expected-error {{'x' is a private member}} \ |
200 | // expected-error {{cannot cast}} |
201 | (void) d.sx; // expected-error {{'sx' is a private member}} |
202 | } |
203 | void C::test(D &d) { |
204 | (void) d.x; // expected-error {{'x' is a private member}} \ |
205 | // expected-error {{cannot cast}} |
206 | (void) d.sx; // expected-error {{'sx' is a private member}} |
207 | } |
208 | void D::test(D &d) { |
209 | (void) d.x; |
210 | (void) d.sx; |
211 | } |
212 | } |
213 | |
214 | namespace test6 { |
215 | class Static {}; |
216 | class A { |
217 | protected: |
218 | void foo(int); // expected-note 3 {{can only access this member on an object of type}} |
219 | void foo(long); |
220 | static void foo(Static); |
221 | |
222 | static void test(A&); |
223 | }; |
224 | class B : public A { |
225 | static void test(A&); |
226 | }; |
227 | class C : protected A { |
228 | static void test(A&); |
229 | }; |
230 | class D : private B { |
231 | static void test(A&); |
232 | }; |
233 | |
234 | void A::test(A &a) { |
235 | a.foo(10); |
236 | a.foo(Static()); |
237 | } |
238 | void B::test(A &a) { |
239 | a.foo(10); // expected-error {{'foo' is a protected member}} |
240 | a.foo(Static()); |
241 | } |
242 | void C::test(A &a) { |
243 | a.foo(10); // expected-error {{'foo' is a protected member}} |
244 | a.foo(Static()); |
245 | } |
246 | void D::test(A &a) { |
247 | a.foo(10); // expected-error {{'foo' is a protected member}} |
248 | a.foo(Static()); |
249 | } |
250 | } |
251 | |
252 | namespace test7 { |
253 | class Static {}; |
254 | class A { |
255 | protected: |
256 | void foo(int); // expected-note 3 {{must name member using the type of the current context}} |
257 | void foo(long); |
258 | static void foo(Static); |
259 | |
260 | static void test(); |
261 | }; |
262 | class B : public A { |
263 | static void test(); |
264 | }; |
265 | class C : protected A { |
266 | static void test(); |
267 | }; |
268 | class D : private B { |
269 | static void test(); |
270 | }; |
271 | |
272 | void A::test() { |
273 | void (A::*x)(int) = &A::foo; |
274 | void (*sx)(Static) = &A::foo; |
275 | } |
276 | void B::test() { |
277 | void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
278 | void (*sx)(Static) = &A::foo; |
279 | } |
280 | void C::test() { |
281 | void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
282 | void (*sx)(Static) = &A::foo; |
283 | } |
284 | void D::test() { |
285 | void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
286 | void (*sx)(Static) = &A::foo; |
287 | } |
288 | } |
289 | |
290 | namespace test8 { |
291 | class Static {}; |
292 | class A { |
293 | protected: |
294 | void foo(int); // expected-note 3 {{must name member using the type of the current context}} |
295 | void foo(long); |
296 | static void foo(Static); |
297 | |
298 | static void test(); |
299 | }; |
300 | class B : public A { |
301 | static void test(); |
302 | }; |
303 | class C : protected A { |
304 | static void test(); |
305 | }; |
306 | class D : private B { |
307 | static void test(); |
308 | }; |
309 | void call(void (A::*)(int)); |
310 | void calls(void (*)(Static)); |
311 | |
312 | void A::test() { |
313 | call(&A::foo); |
314 | calls(&A::foo); |
315 | } |
316 | void B::test() { |
317 | call(&A::foo); // expected-error {{'foo' is a protected member}} |
318 | calls(&A::foo); |
319 | } |
320 | void C::test() { |
321 | call(&A::foo); // expected-error {{'foo' is a protected member}} |
322 | calls(&A::foo); |
323 | } |
324 | void D::test() { |
325 | call(&A::foo); // expected-error {{'foo' is a protected member}} |
326 | calls(&A::foo); |
327 | } |
328 | } |
329 | |
330 | namespace test9 { |
331 | class A { // expected-note {{member is declared here}} |
332 | protected: int foo(); // expected-note 4 {{declared}} expected-note 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}} |
333 | }; |
334 | |
335 | class B : public A { // expected-note {{member is declared here}} |
336 | friend class D; |
337 | }; |
338 | |
339 | class C : protected B { // expected-note {{declared}} \ |
340 | // expected-note 9 {{constrained}} |
341 | }; |
342 | |
343 | class D : public A { |
344 | static void test(A &a) { |
345 | a.foo(); // expected-error {{'foo' is a protected member}} |
346 | a.A::foo(); // expected-error {{'foo' is a protected member}} |
347 | a.B::foo(); // expected-error {{'foo' is a protected member}} |
348 | a.C::foo(); // expected-error {{'foo' is a protected member}} |
349 | a.D::foo(); // expected-error {{'foo' is a protected member}} |
350 | } |
351 | |
352 | static void test(B &b) { |
353 | b.foo(); |
354 | b.A::foo(); |
355 | b.B::foo(); // accessible as named in A |
356 | b.C::foo(); // expected-error {{'foo' is a protected member}} |
357 | } |
358 | |
359 | static void test(C &c) { |
360 | c.foo(); // expected-error {{'foo' is a protected member}} \ |
361 | // expected-error {{cannot cast}} |
362 | c.A::foo(); // expected-error {{'A' is a protected member}} \ |
363 | // expected-error {{cannot cast}} |
364 | c.B::foo(); // expected-error {{'B' is a protected member}} \ |
365 | // expected-error {{cannot cast}} |
366 | c.C::foo(); // expected-error {{'foo' is a protected member}} \ |
367 | // expected-error {{cannot cast}} |
368 | } |
369 | |
370 | static void test(D &d) { |
371 | d.foo(); |
372 | d.A::foo(); |
373 | d.B::foo(); |
374 | d.C::foo(); // expected-error {{'foo' is a protected member}} |
375 | } |
376 | }; |
377 | } |
378 | |
379 | namespace test10 { |
380 | template<typename T> class A { |
381 | protected: |
382 | int foo(); |
383 | int foo() const; |
384 | |
385 | ~A() { foo(); } |
386 | }; |
387 | |
388 | template class A<int>; |
389 | } |
390 | |
391 | // rdar://problem/8360285: class.protected friendship |
392 | namespace test11 { |
393 | class A { |
394 | protected: |
395 | int foo(); |
396 | }; |
397 | |
398 | class B : public A { |
399 | friend class C; |
400 | }; |
401 | |
402 | class C { |
403 | void test() { |
404 | B b; |
405 | b.A::foo(); |
406 | } |
407 | }; |
408 | } |
409 | |
410 | // This friendship is considered because a public member of A would be |
411 | // a private member of C. |
412 | namespace test12 { |
413 | class A { protected: int foo(); }; |
414 | class B : public virtual A {}; |
415 | class C : private B { friend void test(); }; |
416 | class D : private C, public virtual A {}; |
417 | |
418 | void test() { |
419 | D d; |
420 | d.A::foo(); |
421 | } |
422 | } |
423 | |
424 | // This friendship is not considered because a public member of A is |
425 | // inaccessible in C. |
426 | namespace test13 { |
427 | class A { protected: int foo(); }; // expected-note {{declared protected here}} |
428 | class B : private virtual A {}; |
429 | class C : private B { friend void test(); }; |
430 | class D : public virtual A {}; |
431 | |
432 | void test() { |
433 | D d; |
434 | d.A::foo(); // expected-error {{protected member}} |
435 | } |
436 | } |
437 | |
438 | // PR8058 |
439 | namespace test14 { |
440 | class A { |
441 | protected: |
442 | template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}} |
443 | |
444 | void nontemp(int); // expected-note {{must name member using the type of the current context}} |
445 | |
446 | template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}} |
447 | void ovl_temp(float); |
448 | |
449 | void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}} |
450 | void ovl_nontemp(float); |
451 | |
452 | template <class T> void ovl_withtemp(T); |
453 | void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}} |
454 | }; |
455 | |
456 | class B : public A { |
457 | void use() { |
458 | void (A::*ptr)(int); |
459 | ptr = &A::temp; // expected-error {{protected member}} |
460 | ptr = &A::nontemp; // expected-error {{protected member}} |
461 | ptr = &A::ovl_temp; // expected-error {{protected member}} |
462 | ptr = &A::ovl_nontemp; // expected-error {{protected member}} |
463 | ptr = &A::ovl_withtemp; // expected-error {{protected member}} |
464 | } |
465 | }; |
466 | } |
467 | |
468 | namespace test15 { |
469 | class A { |
470 | protected: |
471 | A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}} |
472 | A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}} |
473 | ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}} |
474 | }; |
475 | |
476 | class B : public A { |
477 | // The uses here are fine. |
478 | B() {} |
479 | B(int i) : A() {} |
480 | ~B() {} |
481 | |
482 | // All these uses are bad. |
483 | |
484 | void test0() { |
485 | A a; // expected-error {{protected constructor}} expected-error {{protected destructor}} |
486 | } |
487 | |
488 | A *test1() { |
489 | return new A(); // expected-error {{protected constructor}} |
490 | } |
491 | |
492 | void test2(A *a) { |
493 | delete a; // expected-error {{protected destructor}} |
494 | } |
495 | |
496 | A test3(A *a) { |
497 | return *a; // expected-error {{protected constructor}} |
498 | } |
499 | |
500 | void test4(A *a) { |
501 | a->~A(); // expected-error {{protected member}} |
502 | } |
503 | }; |
504 | } |
505 | |
506 | namespace test16 { |
507 | class A { |
508 | protected: |
509 | ~A(); |
510 | }; |
511 | |
512 | class B : public virtual A { |
513 | public: |
514 | ~B() {} |
515 | }; |
516 | |
517 | class C : public B { |
518 | ~C() {} |
519 | }; |
520 | } |
521 | |