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