John McCall | 7002f4c | 2010-04-09 19:03:51 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
John McCall | 2f51448 | 2010-01-27 03:50:35 +0000 | [diff] [blame] | 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 | |
John McCall | b13b737 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 18 | struct Public {}; struct Protected {}; struct Private {}; |
| 19 | |
John McCall | 2f51448 | 2010-01-27 03:50:35 +0000 | [diff] [blame] | 20 | namespace test0 { |
| 21 | class A { |
| 22 | typedef int type; // expected-note {{declared private here}} |
| 23 | type foo(); |
| 24 | }; |
| 25 | |
John McCall | 6b2accb | 2010-02-10 09:31:12 +0000 | [diff] [blame] | 26 | A::type foo() { } // expected-error {{'type' is a private member}} |
John McCall | 2f51448 | 2010-01-27 03:50:35 +0000 | [diff] [blame] | 27 | A::type A::foo() { } |
| 28 | } |
John McCall | b13b737 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 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 | |
| 45 | void test() { |
| 46 | A a; |
| 47 | Public pub = a; |
John McCall | 6b2accb | 2010-02-10 09:31:12 +0000 | [diff] [blame] | 48 | Protected prot = a; // expected-error {{'operator Protected' is a protected member}} |
| 49 | Private priv = a; // expected-error {{'operator Private' is a private member}} |
John McCall | b13b737 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 50 | A apub = pub; |
John McCall | 6b2accb | 2010-02-10 09:31:12 +0000 | [diff] [blame] | 51 | A aprot = prot; // expected-error {{protected constructor}} |
| 52 | A apriv = priv; // expected-error {{private constructor}} |
John McCall | b13b737 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 53 | } |
| 54 | } |
John McCall | f581382 | 2010-04-29 00:35:03 +0000 | [diff] [blame] | 55 | |
| 56 | // PR6967 |
| 57 | namespace 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 | |
| 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(); |
| 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'}} |
| 106 | } |
| 107 | } |
John McCall | 7576a65 | 2010-04-29 01:20:45 +0000 | [diff] [blame] | 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 | |
| 115 | template <class U> void foo(U &, typename U::type) {} |
| 116 | |
| 117 | void test() { |
| 118 | A<int> a; |
| 119 | foo(a, 0); |
| 120 | } |
| 121 | } |
John McCall | c9068d7 | 2010-07-16 08:13:16 +0000 | [diff] [blame] | 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 | |
| 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 | } |
John McCall | b25b295 | 2011-02-15 07:12:36 +0000 | [diff] [blame] | 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 | } |
John McCall | 4bfd680 | 2011-02-15 22:51:53 +0000 | [diff] [blame] | 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 | }; |
| 167 | void A::check() { |
| 168 | void foo(int arg[__builtin_offsetof(B, ins)]); |
| 169 | } |
| 170 | } |