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 | |
26 | A::type foo() { } // expected-error {{'type' is a private member}} |
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 | |
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: |
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(); // 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 | |
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 | |
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 | // 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 | } |
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 | }; |
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 | |
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 | |
189 | void test(A &a) { |
190 | delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}} |
191 | } |
192 | } |
193 | |