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