p1.cpp revision 637619b915888ead5576d19508644e4eb9024078
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3namespace 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
35namespace 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
69namespace 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
103namespace 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
138namespace 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
176namespace 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
214namespace 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
252namespace 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
290namespace 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
330namespace 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
379namespace 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
392namespace 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.
412namespace 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.
426namespace 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
439namespace 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
468namespace 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
506namespace 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