1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li 3*67e74705SXin Li // C++0x [class.access]p6: 4*67e74705SXin Li // All access controls in [class.access] affect the ability to 5*67e74705SXin Li // access a class member name from a particular scope. For purposes 6*67e74705SXin Li // of access control, the base-specifiers of a class and the 7*67e74705SXin Li // definitions of class members that appear outside of the class 8*67e74705SXin Li // definition are considered to be within the scope of that 9*67e74705SXin Li // class. In particular, access controls apply as usual to member 10*67e74705SXin Li // names accessed as part of a function return type, even though it 11*67e74705SXin Li // is not possible to determine the access privileges of that use 12*67e74705SXin Li // without first parsing the rest of the function 13*67e74705SXin Li // declarator. Similarly, access control for implicit calls to the 14*67e74705SXin Li // constructors, the conversion functions, or the destructor called 15*67e74705SXin Li // to create and destroy a static data member is performed as if 16*67e74705SXin Li // these calls appeared in the scope of the member's class. 17*67e74705SXin Li 18*67e74705SXin Li struct Public {}; struct Protected {}; struct Private {}; 19*67e74705SXin Li 20*67e74705SXin Li namespace test0 { 21*67e74705SXin Li class A { 22*67e74705SXin Li typedef int type; // expected-note {{declared private here}} 23*67e74705SXin Li type foo(); 24*67e74705SXin Li }; 25*67e74705SXin Li foo()26*67e74705SXin Li A::type foo() { } // expected-error {{'type' is a private member}} foo()27*67e74705SXin Li A::type A::foo() { } 28*67e74705SXin Li } 29*67e74705SXin Li 30*67e74705SXin Li // conversion decls 31*67e74705SXin Li namespace test1 { 32*67e74705SXin Li class A { 33*67e74705SXin Li public: 34*67e74705SXin Li A(); 35*67e74705SXin Li operator Public (); 36*67e74705SXin Li A(Public); 37*67e74705SXin Li protected: 38*67e74705SXin Li operator Protected (); // expected-note {{declared protected here}} 39*67e74705SXin Li A(Protected); // expected-note {{declared protected here}} 40*67e74705SXin Li private: 41*67e74705SXin Li operator Private (); // expected-note {{declared private here}} 42*67e74705SXin Li A(Private); // expected-note {{declared private here}} 43*67e74705SXin Li }; 44*67e74705SXin Li test()45*67e74705SXin Li void test() { 46*67e74705SXin Li A a; 47*67e74705SXin Li Public pub = a; 48*67e74705SXin Li Protected prot = a; // expected-error {{'operator Protected' is a protected member}} 49*67e74705SXin Li Private priv = a; // expected-error {{'operator Private' is a private member}} 50*67e74705SXin Li A apub = pub; 51*67e74705SXin Li A aprot = prot; // expected-error {{protected constructor}} 52*67e74705SXin Li A apriv = priv; // expected-error {{private constructor}} 53*67e74705SXin Li } 54*67e74705SXin Li } 55*67e74705SXin Li 56*67e74705SXin Li // PR6967 57*67e74705SXin Li namespace test2 { 58*67e74705SXin Li class A { 59*67e74705SXin Li public: set(T & t,typename T::type v)60*67e74705SXin Li template <class T> static void set(T &t, typename T::type v) { 61*67e74705SXin Li t.value = v; 62*67e74705SXin Li } get(const T & t)63*67e74705SXin Li template <class T> static typename T::type get(const T &t) { 64*67e74705SXin Li return t.value; 65*67e74705SXin Li } 66*67e74705SXin Li }; 67*67e74705SXin Li 68*67e74705SXin Li class B { 69*67e74705SXin Li friend class A; 70*67e74705SXin Li 71*67e74705SXin Li private: 72*67e74705SXin Li typedef int type; 73*67e74705SXin Li type value; 74*67e74705SXin Li }; 75*67e74705SXin Li test()76*67e74705SXin Li int test() { 77*67e74705SXin Li B b; 78*67e74705SXin Li A::set(b, 0); 79*67e74705SXin Li return A::get(b); 80*67e74705SXin Li } 81*67e74705SXin Li } 82*67e74705SXin Li 83*67e74705SXin Li namespace test3 { 84*67e74705SXin Li class Green {}; class Blue {}; 85*67e74705SXin Li 86*67e74705SXin Li // We have to wrap this in a class because a partial specialization 87*67e74705SXin Li // isn't actually in the context of the template. 88*67e74705SXin Li struct Outer { 89*67e74705SXin Li template <class T, class Nat> class A { 90*67e74705SXin Li }; 91*67e74705SXin Li }; 92*67e74705SXin Li 93*67e74705SXin Li template <class T> class Outer::A<T, typename T::nature> { 94*67e74705SXin Li public: 95*67e74705SXin Li static void foo(); // expected-note {{'Outer::A<B, Green>::foo' declared here}} 96*67e74705SXin Li }; 97*67e74705SXin Li 98*67e74705SXin Li class B { 99*67e74705SXin Li private: typedef Green nature; 100*67e74705SXin Li friend class Outer; 101*67e74705SXin Li }; 102*67e74705SXin Li test()103*67e74705SXin Li void test() { 104*67e74705SXin Li Outer::A<B, Green>::foo(); 105*67e74705SXin Li Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<B, Green>::foo'?}} 106*67e74705SXin Li } 107*67e74705SXin Li } 108*67e74705SXin Li 109*67e74705SXin Li namespace test4 { 110*67e74705SXin Li template <class T> class A { 111*67e74705SXin Li private: typedef int type; 112*67e74705SXin Li template <class U> friend void foo(U &, typename U::type); 113*67e74705SXin Li }; 114*67e74705SXin Li foo(U &,typename U::type)115*67e74705SXin Li template <class U> void foo(U &, typename U::type) {} 116*67e74705SXin Li test()117*67e74705SXin Li void test() { 118*67e74705SXin Li A<int> a; 119*67e74705SXin Li foo(a, 0); 120*67e74705SXin Li } 121*67e74705SXin Li } 122*67e74705SXin Li 123*67e74705SXin Li // PR7644 124*67e74705SXin Li namespace test5 { 125*67e74705SXin Li class A { 126*67e74705SXin Li enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}} 127*67e74705SXin Li template <Enum> void foo(); 128*67e74705SXin Li template <Enum> class bar; 129*67e74705SXin Li }; 130*67e74705SXin Li foo()131*67e74705SXin Li template <A::Enum en> void A::foo() {} 132*67e74705SXin Li template <A::Enum en> class A::bar {}; 133*67e74705SXin Li foo()134*67e74705SXin Li template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}} 135*67e74705SXin Li template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}} 136*67e74705SXin Li 137*67e74705SXin Li class B { foo()138*67e74705SXin Li template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}} 139*67e74705SXin Li template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}} 140*67e74705SXin Li }; 141*67e74705SXin Li } 142*67e74705SXin Li 143*67e74705SXin Li namespace test6 { 144*67e74705SXin Li class A { 145*67e74705SXin Li public: class public_inner {}; 146*67e74705SXin Li protected: class protected_inner {}; 147*67e74705SXin Li private: class private_inner {}; // expected-note {{declared private here}} 148*67e74705SXin Li }; 149*67e74705SXin Li 150*67e74705SXin Li class B : A { 151*67e74705SXin Li public_inner a; 152*67e74705SXin Li protected_inner b; 153*67e74705SXin Li private_inner c; // expected-error {{'private_inner' is a private member of 'test6::A'}} 154*67e74705SXin Li }; 155*67e74705SXin Li } 156*67e74705SXin Li 157*67e74705SXin Li // PR9229 158*67e74705SXin Li namespace test7 { 159*67e74705SXin Li void foo(int arg[1]); 160*67e74705SXin Li class A { 161*67e74705SXin Li void check(); 162*67e74705SXin Li }; 163*67e74705SXin Li class B { 164*67e74705SXin Li friend class A; 165*67e74705SXin Li A ins; 166*67e74705SXin Li }; check()167*67e74705SXin Li void A::check() { 168*67e74705SXin Li void foo(int arg[__builtin_offsetof(B, ins)]); 169*67e74705SXin Li } 170*67e74705SXin Li } 171*67e74705SXin Li 172*67e74705SXin Li // rdar://problem/10155256 173*67e74705SXin Li namespace test8 { 174*67e74705SXin Li class A { 175*67e74705SXin Li typedef void* (A::*UnspecifiedBoolType)() const; 176*67e74705SXin Li operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}} 177*67e74705SXin Li }; 178*67e74705SXin Li test(A & a)179*67e74705SXin Li void test(A &a) { 180*67e74705SXin Li if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}} 181*67e74705SXin Li } 182*67e74705SXin Li } 183*67e74705SXin Li 184*67e74705SXin Li namespace test9 { 185*67e74705SXin Li class A { 186*67e74705SXin Li operator char*() const; // expected-note {{implicitly declared private here}} 187*67e74705SXin Li }; 188*67e74705SXin Li test(A & a)189*67e74705SXin Li void test(A &a) { 190*67e74705SXin Li delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}} 191*67e74705SXin Li } 192*67e74705SXin Li } 193