192 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3// C++0x [class.access]p6:4// All access controls in [class.access] affect the ability to5// access a class member name from a particular scope. For purposes6// of access control, the base-specifiers of a class and the7// definitions of class members that appear outside of the class8// definition are considered to be within the scope of that9// class. In particular, access controls apply as usual to member10// names accessed as part of a function return type, even though it11// is not possible to determine the access privileges of that use12// without first parsing the rest of the function13// declarator. Similarly, access control for implicit calls to the14// constructors, the conversion functions, or the destructor called15// to create and destroy a static data member is performed as if16// these calls appeared in the scope of the member's class.17 18struct Public {}; struct Protected {}; struct Private {};19 20namespace test0 {21 class A {22 typedef int type; // expected-note {{declared private here}}23 type foo();24 };25 26 A::type foo() { } // expected-error {{'type' is a private member}}27 A::type A::foo() { }28}29 30// conversion decls31namespace 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 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// PR696757namespace test2 {58 class A {59 public:60 template <class T> static void set(T &t, typename T::type v) {61 t.value = v;62 }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 76 int test() {77 B b;78 A::set(b, 0);79 return A::get(b);80 }81}82 83namespace test3 {84 class Green {}; class Blue {};85 86 // We have to wrap this in a class because a partial specialization87 // 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<test3::B, test3::Green>::foo' declared here}}96 };97 98 class B {99 private: typedef Green nature;100 friend class Outer;101 };102 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<test3::B, test3::Green>::foo'?}}106 }107}108 109namespace 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 115 template <class U> void foo(U &, typename U::type) {}116 117 void test() {118 A<int> a;119 foo(a, 0);120 }121}122 123// PR7644124namespace 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 131 template <A::Enum en> void A::foo() {}132 template <A::Enum en> class A::bar {};133 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 {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 143namespace 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// PR9229158namespace 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 };167 void A::check() {168 void foo(int arg[__builtin_offsetof(B, ins)]);169 }170}171 172namespace test8 {173 class A {174 typedef void* (A::*UnspecifiedBoolType)() const;175 operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}176 };177 178 void test(A &a) {179 if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}180 }181}182 183namespace test9 {184 class A {185 operator char*() const; // expected-note {{implicitly declared private here}}186 };187 188 void test(A &a) {189 delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}190 }191}192