| // RUN: %clang_cc1 -fsyntax-only -verify %s |
| |
| namespace test0 { |
| class A { |
| protected: int x; // expected-note 3 {{declared}} \ |
| // expected-note {{member is declared here}} |
| static int sx; // expected-note 3 {{declared}} \ |
| // expected-note {{member is declared here}} |
| }; |
| class B : public A { |
| }; |
| class C : protected A { // expected-note {{declared}} |
| }; |
| class D : private B { // expected-note 3 {{constrained}} |
| }; |
| |
| void test(A &a) { |
| (void) a.x; // expected-error {{'x' is a protected member}} |
| (void) a.sx; // expected-error {{'sx' is a protected member}} |
| } |
| void test(B &b) { |
| (void) b.x; // expected-error {{'x' is a protected member}} |
| (void) b.sx; // expected-error {{'sx' is a protected member}} |
| } |
| void test(C &c) { |
| (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}} |
| (void) c.sx; // expected-error {{'sx' is a protected member}} |
| } |
| void test(D &d) { |
| (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}} |
| (void) d.sx; // expected-error {{'sx' is a private member}} |
| } |
| } |
| |
| namespace test1 { |
| class A { |
| protected: int x; |
| static int sx; |
| static void test(A&); |
| }; |
| class B : public A { |
| static void test(B&); |
| }; |
| class C : protected A { |
| static void test(C&); |
| }; |
| class D : private B { |
| static void test(D&); |
| }; |
| |
| void A::test(A &a) { |
| (void) a.x; |
| (void) a.sx; |
| } |
| void B::test(B &b) { |
| (void) b.x; |
| (void) b.sx; |
| } |
| void C::test(C &c) { |
| (void) c.x; |
| (void) c.sx; |
| } |
| void D::test(D &d) { |
| (void) d.x; |
| (void) d.sx; |
| } |
| } |
| |
| namespace test2 { |
| class A { |
| protected: int x; // expected-note 3 {{object type must derive}} |
| static int sx; |
| static void test(A&); |
| }; |
| class B : public A { |
| static void test(A&); |
| }; |
| class C : protected A { |
| static void test(A&); |
| }; |
| class D : private B { |
| static void test(A&); |
| }; |
| |
| void A::test(A &a) { |
| (void) a.x; |
| (void) a.sx; |
| } |
| void B::test(A &a) { |
| (void) a.x; // expected-error {{'x' is a protected member}} |
| (void) a.sx; |
| } |
| void C::test(A &a) { |
| (void) a.x; // expected-error {{'x' is a protected member}} |
| (void) a.sx; |
| } |
| void D::test(A &a) { |
| (void) a.x; // expected-error {{'x' is a protected member}} |
| (void) a.sx; |
| } |
| } |
| |
| namespace test3 { |
| class B; |
| class A { |
| protected: int x; // expected-note {{object type must derive}} |
| static int sx; |
| static void test(B&); |
| }; |
| class B : public A { |
| static void test(B&); |
| }; |
| class C : protected A { |
| static void test(B&); |
| }; |
| class D : private B { |
| static void test(B&); |
| }; |
| |
| void A::test(B &b) { |
| (void) b.x; |
| (void) b.sx; |
| } |
| void B::test(B &b) { |
| (void) b.x; |
| (void) b.sx; |
| } |
| void C::test(B &b) { |
| (void) b.x; // expected-error {{'x' is a protected member}} |
| (void) b.sx; |
| } |
| void D::test(B &b) { |
| (void) b.x; |
| (void) b.sx; |
| } |
| } |
| |
| namespace test4 { |
| class C; |
| class A { |
| protected: int x; // expected-note {{declared}} expected-note 2 {{object type must derive}} |
| static int sx; // expected-note 3{{member is declared here}} |
| static void test(C&); |
| }; |
| class B : public A { |
| static void test(C&); |
| }; |
| class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}} |
| static void test(C&); |
| }; |
| class D : private B { |
| static void test(C&); |
| }; |
| |
| void A::test(C &c) { |
| (void) c.x; // expected-error {{'x' is a protected member}} \ |
| // expected-error {{protected base class}} |
| (void) c.sx; // expected-error {{'sx' is a protected member}} |
| } |
| void B::test(C &c) { |
| (void) c.x; // expected-error {{'x' is a protected member}} \ |
| // expected-error {{protected base class}} |
| (void) c.sx; // expected-error {{'sx' is a protected member}} |
| } |
| void C::test(C &c) { |
| (void) c.x; |
| (void) c.sx; |
| } |
| void D::test(C &c) { |
| (void) c.x; // expected-error {{'x' is a protected member}} \ |
| // expected-error {{protected base class}} |
| (void) c.sx; // expected-error {{'sx' is a protected member}} |
| } |
| } |
| |
| namespace test5 { |
| class D; |
| class A { |
| protected: int x; // expected-note 3{{member is declared here}} |
| static int sx; // expected-note 3{{member is declared here}} |
| static void test(D&); |
| }; |
| class B : public A { |
| static void test(D&); |
| }; |
| class C : protected A { |
| static void test(D&); |
| }; |
| class D : private B { // expected-note 9 {{constrained}} |
| static void test(D&); |
| }; |
| |
| void A::test(D &d) { |
| (void) d.x; // expected-error {{'x' is a private member}} \ |
| // expected-error {{cannot cast}} |
| (void) d.sx; // expected-error {{'sx' is a private member}} |
| } |
| void B::test(D &d) { |
| (void) d.x; // expected-error {{'x' is a private member}} \ |
| // expected-error {{cannot cast}} |
| (void) d.sx; // expected-error {{'sx' is a private member}} |
| } |
| void C::test(D &d) { |
| (void) d.x; // expected-error {{'x' is a private member}} \ |
| // expected-error {{cannot cast}} |
| (void) d.sx; // expected-error {{'sx' is a private member}} |
| } |
| void D::test(D &d) { |
| (void) d.x; |
| (void) d.sx; |
| } |
| } |
| |
| namespace test6 { |
| class Static {}; |
| class A { |
| protected: |
| void foo(int); // expected-note 3 {{object type must derive}} |
| void foo(long); |
| static void foo(Static); |
| |
| static void test(A&); |
| }; |
| class B : public A { |
| static void test(A&); |
| }; |
| class C : protected A { |
| static void test(A&); |
| }; |
| class D : private B { |
| static void test(A&); |
| }; |
| |
| void A::test(A &a) { |
| a.foo(10); |
| a.foo(Static()); |
| } |
| void B::test(A &a) { |
| a.foo(10); // expected-error {{'foo' is a protected member}} |
| a.foo(Static()); |
| } |
| void C::test(A &a) { |
| a.foo(10); // expected-error {{'foo' is a protected member}} |
| a.foo(Static()); |
| } |
| void D::test(A &a) { |
| a.foo(10); // expected-error {{'foo' is a protected member}} |
| a.foo(Static()); |
| } |
| } |
| |
| namespace test7 { |
| class Static {}; |
| class A { |
| protected: |
| void foo(int); // expected-note 3 {{object type must derive}} |
| void foo(long); |
| static void foo(Static); |
| |
| static void test(); |
| }; |
| class B : public A { |
| static void test(); |
| }; |
| class C : protected A { |
| static void test(); |
| }; |
| class D : private B { |
| static void test(); |
| }; |
| |
| void A::test() { |
| void (A::*x)(int) = &A::foo; |
| void (*sx)(Static) = &A::foo; |
| } |
| void B::test() { |
| void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
| void (*sx)(Static) = &A::foo; |
| } |
| void C::test() { |
| void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
| void (*sx)(Static) = &A::foo; |
| } |
| void D::test() { |
| void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} |
| void (*sx)(Static) = &A::foo; |
| } |
| } |
| |
| namespace test8 { |
| class Static {}; |
| class A { |
| protected: |
| void foo(int); // expected-note 3 {{object type must derive}} |
| void foo(long); |
| static void foo(Static); |
| |
| static void test(); |
| }; |
| class B : public A { |
| static void test(); |
| }; |
| class C : protected A { |
| static void test(); |
| }; |
| class D : private B { |
| static void test(); |
| }; |
| void call(void (A::*)(int)); |
| void calls(void (*)(Static)); |
| |
| void A::test() { |
| call(&A::foo); |
| calls(&A::foo); |
| } |
| void B::test() { |
| call(&A::foo); // expected-error {{'foo' is a protected member}} |
| calls(&A::foo); |
| } |
| void C::test() { |
| call(&A::foo); // expected-error {{'foo' is a protected member}} |
| calls(&A::foo); |
| } |
| void D::test() { |
| call(&A::foo); // expected-error {{'foo' is a protected member}} |
| calls(&A::foo); |
| } |
| } |
| |
| namespace test9 { |
| class A { // expected-note {{member is declared here}} |
| protected: int foo(); // expected-note 4 {{declared}} expected-note 2 {{object type must derive}} expected-note {{object type 'test9::A' must derive}} |
| }; |
| |
| class B : public A { // expected-note {{member is declared here}} |
| friend class D; |
| }; |
| |
| class C : protected B { // expected-note {{declared}} \ |
| // expected-note 9 {{constrained}} |
| }; |
| |
| class D : public A { |
| static void test(A &a) { |
| a.foo(); // expected-error {{'foo' is a protected member}} |
| a.A::foo(); // expected-error {{'foo' is a protected member}} |
| a.B::foo(); |
| a.C::foo(); // expected-error {{'foo' is a protected member}} |
| } |
| |
| static void test(B &b) { |
| b.foo(); |
| b.A::foo(); |
| b.B::foo(); |
| b.C::foo(); // expected-error {{'foo' is a protected member}} |
| } |
| |
| static void test(C &c) { |
| c.foo(); // expected-error {{'foo' is a protected member}} \ |
| // expected-error {{cannot cast}} |
| c.A::foo(); // expected-error {{'A' is a protected member}} \ |
| // expected-error {{cannot cast}} |
| c.B::foo(); // expected-error {{'B' is a protected member}} \ |
| // expected-error {{cannot cast}} |
| c.C::foo(); // expected-error {{'foo' is a protected member}} \ |
| // expected-error {{cannot cast}} |
| } |
| |
| static void test(D &d) { |
| d.foo(); |
| d.A::foo(); |
| d.B::foo(); |
| d.C::foo(); // expected-error {{'foo' is a protected member}} |
| } |
| }; |
| } |
| |
| namespace test10 { |
| template<typename T> class A { |
| protected: |
| int foo(); |
| int foo() const; |
| |
| ~A() { foo(); } |
| }; |
| |
| template class A<int>; |
| } |
| |
| // rdar://problem/8360285: class.protected friendship |
| namespace test11 { |
| class A { |
| protected: |
| int foo(); |
| }; |
| |
| class B : public A { |
| friend class C; |
| }; |
| |
| class C { |
| void test() { |
| B b; |
| b.A::foo(); |
| } |
| }; |
| } |
| |
| // This friendship is considered because a public member of A would be |
| // a private member of C. |
| namespace test12 { |
| class A { protected: int foo(); }; |
| class B : public virtual A {}; |
| class C : private B { friend void test(); }; |
| class D : private C, public virtual A {}; |
| |
| void test() { |
| D d; |
| d.A::foo(); |
| } |
| } |
| |
| // This friendship is not considered because a public member of A is |
| // inaccessible in C. |
| namespace test13 { |
| class A { protected: int foo(); }; // expected-note {{object type 'test13::D' must derive from context type 'test13::C'}} |
| class B : private virtual A {}; |
| class C : private B { friend void test(); }; |
| class D : public virtual A {}; |
| |
| void test() { |
| D d; |
| d.A::foo(); // expected-error {{protected member}} |
| } |
| } |