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