p1.cpp revision b9abd87283ac6e929b7e12a577663bc99e61d020
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 2 {{can only access this member on an object of type}} expected-note {{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();
348      a.C::foo(); // expected-error {{'foo' is a protected member}}
349    }
350
351    static void test(B &b) {
352      b.foo();
353      b.A::foo();
354      b.B::foo();
355      b.C::foo(); // expected-error {{'foo' is a protected member}}
356    }
357
358    static void test(C &c) {
359      c.foo();    // expected-error {{'foo' is a protected member}} \
360                  // expected-error {{cannot cast}}
361      c.A::foo(); // expected-error {{'A' is a protected member}} \
362                  // expected-error {{cannot cast}}
363      c.B::foo(); // expected-error {{'B' is a protected member}} \
364                  // expected-error {{cannot cast}}
365      c.C::foo(); // expected-error {{'foo' is a protected member}} \
366                  // expected-error {{cannot cast}}
367    }
368
369    static void test(D &d) {
370      d.foo();
371      d.A::foo();
372      d.B::foo();
373      d.C::foo(); // expected-error {{'foo' is a protected member}}
374    }
375  };
376}
377
378namespace test10 {
379  template<typename T> class A {
380  protected:
381    int foo();
382    int foo() const;
383
384    ~A() { foo(); }
385  };
386
387  template class A<int>;
388}
389
390// rdar://problem/8360285: class.protected friendship
391namespace test11 {
392  class A {
393  protected:
394    int foo();
395  };
396
397  class B : public A {
398    friend class C;
399  };
400
401  class C {
402    void test() {
403      B b;
404      b.A::foo();
405    }
406  };
407}
408
409// This friendship is considered because a public member of A would be
410// a private member of C.
411namespace test12 {
412  class A { protected: int foo(); };
413  class B : public virtual A {};
414  class C : private B { friend void test(); };
415  class D : private C, public virtual A {};
416
417  void test() {
418    D d;
419    d.A::foo();
420  }
421}
422
423// This friendship is not considered because a public member of A is
424// inaccessible in C.
425namespace test13 {
426  class A { protected: int foo(); }; // expected-note {{can only access this member on an object of type}}
427  class B : private virtual A {};
428  class C : private B { friend void test(); };
429  class D : public virtual A {};
430
431  void test() {
432    D d;
433    d.A::foo(); // expected-error {{protected member}}
434  }
435}
436
437// PR8058
438namespace test14 {
439  class A {
440  protected:
441    template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}}
442
443    void nontemp(int); // expected-note {{must name member using the type of the current context}}
444
445    template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}}
446    void ovl_temp(float);
447
448    void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}}
449    void ovl_nontemp(float);
450
451    template <class T> void ovl_withtemp(T);
452    void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}}
453  };
454
455  class B : public A {
456    void use() {
457      void (A::*ptr)(int);
458      ptr = &A::temp; // expected-error {{protected member}}
459      ptr = &A::nontemp; // expected-error {{protected member}}
460      ptr = &A::ovl_temp; // expected-error {{protected member}}
461      ptr = &A::ovl_nontemp; // expected-error {{protected member}}
462      ptr = &A::ovl_withtemp; // expected-error {{protected member}}
463    }
464  };
465}
466
467namespace test15 {
468  class A {
469  protected:
470    A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}}
471    A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}}
472    ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}}
473  };
474
475  class B : public A {
476    // The uses here are fine.
477    B() {}
478    B(int i) : A() {}
479    ~B() {}
480
481    // All these uses are bad.
482
483    void test0() {
484      A a; // expected-error {{protected constructor}} expected-error {{protected destructor}}
485    }
486
487    A *test1() {
488      return new A(); // expected-error {{protected constructor}}
489    }
490
491    void test2(A *a) {
492      delete a; // expected-error {{protected destructor}}
493    }
494
495    A test3(A *a) {
496      return *a; // expected-error {{protected constructor}}
497    }
498
499    void test4(A *a) {
500      a->~A(); // expected-error {{protected member}}
501    }
502  };
503}
504