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