// 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 {{can only access this member on an object of type}} 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 {{declared protected}} // expected-note {{can only access this member on an object of type}} 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; // expected-error {{'x' is a protected member}} (void) b.sx; } } namespace test4 { class C; class A { protected: int x; // expected-note 2{{declared protected here}} expected-note{{member is declared here}} 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 {{can only access this member on an object of type}} 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 {{must name member using the type of the current context}} 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 {{must name member using the type of the current context}} 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 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}} }; 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(); // expected-error {{'foo' is a protected member}} a.C::foo(); // expected-error {{'foo' is a protected member}} a.D::foo(); // expected-error {{'foo' is a protected member}} } static void test(B &b) { b.foo(); b.A::foo(); b.B::foo(); // accessible as named in A 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 {{declared protected here}} 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}} } } // PR8058 namespace test14 { class A { protected: template <class T> void temp(T t); // expected-note {{must name member using the type of the current context}} void nontemp(int); // expected-note {{must name member using the type of the current context}} template <class T> void ovl_temp(T t); // expected-note {{must name member using the type of the current context}} void ovl_temp(float); void ovl_nontemp(int); // expected-note {{must name member using the type of the current context}} void ovl_nontemp(float); template <class T> void ovl_withtemp(T); void ovl_withtemp(int); // expected-note {{must name member using the type of the current context}} }; class B : public A { void use() { void (A::*ptr)(int); ptr = &A::temp; // expected-error {{protected member}} ptr = &A::nontemp; // expected-error {{protected member}} ptr = &A::ovl_temp; // expected-error {{protected member}} ptr = &A::ovl_nontemp; // expected-error {{protected member}} ptr = &A::ovl_withtemp; // expected-error {{protected member}} } }; } namespace test15 { class A { protected: A(); // expected-note 2 {{protected constructor can only be used to construct a base class subobject}} A(const A &); // expected-note {{protected constructor can only be used to construct a base class subobject}} ~A(); // expected-note 3 {{protected destructor can only be used to destroy a base class subobject}} }; class B : public A { // The uses here are fine. B() {} B(int i) : A() {} ~B() {} // All these uses are bad. void test0() { A a; // expected-error {{protected constructor}} expected-error {{protected destructor}} } A *test1() { return new A(); // expected-error {{protected constructor}} } void test2(A *a) { delete a; // expected-error {{protected destructor}} } A test3(A *a) { return *a; // expected-error {{protected constructor}} } void test4(A *a) { a->~A(); // expected-error {{protected member}} } }; } namespace test16 { class A { protected: ~A(); }; class B : public virtual A { public: ~B() {} }; class C : public B { ~C() {} }; }