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