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 | } |