1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 |
2 | |
3 | friend class A; // expected-error {{'friend' used outside of class}} |
4 | void f() { friend class A; } // expected-error {{'friend' used outside of class}} |
5 | class C { friend class A; }; |
6 | class D { void f() { friend class A; } }; // expected-error {{'friend' used outside of class}} |
7 | |
8 | // PR5760 |
9 | namespace test0 { |
10 | namespace ns { |
11 | void f(int); |
12 | } |
13 | |
14 | struct A { |
15 | friend void ns::f(int a); |
16 | }; |
17 | } |
18 | |
19 | // Test derived from LLVM's Registry.h |
20 | namespace test1 { |
21 | template <class T> struct Outer { |
22 | void foo(T); |
23 | struct Inner { |
24 | friend void Outer::foo(T); |
25 | }; |
26 | }; |
27 | |
28 | void test() { |
29 | (void) Outer<int>::Inner(); |
30 | } |
31 | } |
32 | |
33 | // PR5476 |
34 | namespace test2 { |
35 | namespace foo { |
36 | void Func(int x); |
37 | } |
38 | |
39 | class Bar { |
40 | friend void ::test2::foo::Func(int x); |
41 | }; |
42 | } |
43 | |
44 | // PR5134 |
45 | namespace test3 { |
46 | class Foo { |
47 | friend const int getInt(int inInt = 0) {} |
48 | |
49 | }; |
50 | } |
51 | |
52 | namespace test4 { |
53 | class T4A { |
54 | friend class T4B; |
55 | |
56 | public: |
57 | T4A(class T4B *); |
58 | |
59 | protected: |
60 | T4B *mB; // error here |
61 | }; |
62 | |
63 | class T4B {}; |
64 | } |
65 | |
66 | namespace rdar8529993 { |
67 | struct A { ~A(); }; |
68 | |
69 | struct B : A |
70 | { |
71 | template<int> friend A::~A(); // expected-error {{destructor cannot be declared as a template}} |
72 | }; |
73 | } |
74 | |
75 | // PR7915 |
76 | namespace test5 { |
77 | struct A; |
78 | struct A1 { friend void A(); }; |
79 | |
80 | struct B { friend void B(); }; |
81 | } |
82 | |
83 | // PR8479 |
84 | namespace test6_1 { |
85 | class A { |
86 | public: |
87 | private: |
88 | friend class vectorA; |
89 | A() {} |
90 | }; |
91 | class vectorA { |
92 | public: |
93 | vectorA(int i, const A& t = A()) {} |
94 | }; |
95 | void f() { |
96 | vectorA v(1); |
97 | } |
98 | } |
99 | namespace test6_2 { |
100 | template<class T> |
101 | class vector { |
102 | public: |
103 | vector(int i, const T& t = T()) {} |
104 | }; |
105 | class A { |
106 | public: |
107 | private: |
108 | friend class vector<A>; |
109 | A() {} |
110 | }; |
111 | void f() { |
112 | vector<A> v(1); |
113 | } |
114 | } |
115 | namespace test6_3 { |
116 | template<class T> |
117 | class vector { |
118 | public: |
119 | vector(int i) {} |
120 | void f(const T& t = T()) {} |
121 | }; |
122 | class A { |
123 | public: |
124 | private: |
125 | friend void vector<A>::f(const A&); |
126 | A() {} |
127 | }; |
128 | void f() { |
129 | vector<A> v(1); |
130 | v.f(); |
131 | } |
132 | } |
133 | |
134 | namespace test7 { |
135 | extern "C" { |
136 | class X { |
137 | friend int test7_f() { return 42; } |
138 | }; |
139 | } |
140 | } |
141 | |
142 | // PR15485 |
143 | namespace test8 { |
144 | namespace ns1 { |
145 | namespace ns2 { |
146 | template<class T> void f(T t); // expected-note {{target of using declaration}} |
147 | } |
148 | using ns2::f; // expected-note {{using declaration}} |
149 | } |
150 | struct A { void f(); }; // expected-note 2{{target of using declaration}} |
151 | struct B : public A { using A::f; }; // expected-note {{using declaration}} |
152 | template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}} |
153 | struct X { |
154 | template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}} |
155 | friend void B::f(); // expected-error {{cannot befriend target of using declaration}} |
156 | friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}} |
157 | }; |
158 | } |
159 | |
160 | // PR16423 |
161 | namespace test9 { |
162 | class C { |
163 | }; |
164 | struct A { |
165 | friend void C::f(int, int, int) {} // expected-error {{friend function definition cannot be qualified with 'C::'}} |
166 | }; |
167 | } |
168 | |
169 | namespace test10 { |
170 | struct X {}; |
171 | extern void f10_a(); |
172 | extern void f10_a(X); |
173 | struct A { |
174 | friend void f10_a(); |
175 | friend void f10_b(); |
176 | friend void f10_c(); |
177 | friend void f10_d(); |
178 | friend void f10_a(X); |
179 | friend void f10_b(X); |
180 | friend void f10_c(X); |
181 | friend void f10_d(X); |
182 | }; |
183 | extern void f10_b(); |
184 | extern void f10_b(X); |
185 | struct B { |
186 | friend void f10_a(); |
187 | friend void f10_b(); |
188 | friend void f10_c(); |
189 | friend void f10_d(); |
190 | friend void f10_a(X); |
191 | friend void f10_b(X); |
192 | friend void f10_c(X); |
193 | friend void f10_d(X); |
194 | }; |
195 | extern void f10_c(); |
196 | extern void f10_c(X); |
197 | |
198 | // FIXME: Give a better diagnostic for the case where a function exists but is |
199 | // not visible. |
200 | void g(X x) { |
201 | f10_a(); |
202 | f10_b(); |
203 | f10_c(); |
204 | f10_d(); // expected-error {{undeclared identifier}} |
205 | |
206 | ::test10::f10_a(); |
207 | ::test10::f10_b(); |
208 | ::test10::f10_c(); |
209 | ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} |
210 | |
211 | f10_a(x); |
212 | f10_b(x); |
213 | f10_c(x); |
214 | f10_d(x); // PR16597: expected-error {{undeclared identifier}} |
215 | |
216 | ::test10::f10_a(x); |
217 | ::test10::f10_b(x); |
218 | ::test10::f10_c(x); |
219 | ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} |
220 | } |
221 | |
222 | struct Y : X { |
223 | friend void f10_d(); |
224 | friend void f10_d(X); |
225 | }; |
226 | |
227 | struct Z { |
228 | operator X(); |
229 | friend void f10_d(); |
230 | friend void f10_d(X); |
231 | }; |
232 | |
233 | struct W { |
234 | friend void f10_d(W); |
235 | }; |
236 | |
237 | void g(X x, Y y, Z z) { |
238 | f10_d(); // expected-error {{undeclared identifier}} |
239 | ::test10::f10_d(); // expected-error {{no member named 'f10_d'}} |
240 | |
241 | // f10_d is visible to ADL in the second and third cases. |
242 | f10_d(x); // expected-error {{undeclared identifier}} |
243 | f10_d(y); |
244 | f10_d(z); |
245 | |
246 | // No ADL here. |
247 | ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}} |
248 | ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}} |
249 | ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}} |
250 | } |
251 | |
252 | void local_externs(W w, X x, Y y) { |
253 | extern void f10_d(); // expected-note {{candidate}} |
254 | extern void f10_d(X); // expected-note {{candidate}} |
255 | f10_d(); |
256 | f10_d(x); |
257 | f10_d(y); |
258 | f10_d(w); // expected-error {{no matching}} |
259 | { |
260 | int f10_d; |
261 | f10_d(); // expected-error {{not a function}} |
262 | f10_d(x); // expected-error {{not a function}} |
263 | f10_d(y); // expected-error {{not a function}} |
264 | } |
265 | } |
266 | |
267 | void i(X x, Y y) { |
268 | f10_d(); // expected-error {{undeclared identifier}} |
269 | f10_d(x); // expected-error {{undeclared identifier}} |
270 | f10_d(y); |
271 | } |
272 | |
273 | struct C { |
274 | friend void f10_d(); |
275 | friend void f10_d(X); |
276 | }; |
277 | |
278 | void j(X x, Y y) { |
279 | f10_d(); // expected-error {{undeclared identifier}} |
280 | f10_d(x); // expected-error {{undeclared identifier}} |
281 | f10_d(y); |
282 | } |
283 | |
284 | extern void f10_d(); |
285 | extern void f10_d(X); |
286 | void k(X x, Y y, Z z) { |
287 | // All OK now. |
288 | f10_d(); |
289 | f10_d(x); |
290 | ::test10::f10_d(); |
291 | ::test10::f10_d(x); |
292 | ::test10::f10_d(y); |
293 | ::test10::f10_d(z); |
294 | } |
295 | } |
296 | |
297 | namespace test11 { |
298 | class __attribute__((visibility("hidden"))) B; |
299 | |
300 | class A { |
301 | friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}} |
302 | }; |
303 | } |
304 | |
305 | namespace pr21851 { |
306 | // PR21851 was a problem where we assumed that when the friend function redecl |
307 | // lookup found a C++ method, it would necessarily have a qualifier. Below we |
308 | // have some test cases where unqualified lookup finds C++ methods without using |
309 | // qualifiers. Unfortunately, we can't exercise the case of an access check |
310 | // failure because nested classes always have access to the members of outer |
311 | // classes. |
312 | |
313 | void friend_own_method() { |
314 | class A { |
315 | void m() {} |
316 | friend void m(); |
317 | }; |
318 | } |
319 | |
320 | void friend_enclosing_method() { |
321 | class A; |
322 | class C { |
323 | int p; |
324 | friend class A; |
325 | }; |
326 | class A { |
327 | void enclosing_friend() { |
328 | (void)b->p; |
329 | (void)c->p; |
330 | } |
331 | class B { |
332 | void b(A *a) { |
333 | (void)a->c->p; |
334 | } |
335 | int p; |
336 | friend void enclosing_friend(); |
337 | }; |
338 | B *b; |
339 | C *c; |
340 | }; |
341 | } |
342 | |
343 | static auto friend_file_func() { |
344 | extern void file_scope_friend(); |
345 | class A { |
346 | int p; |
347 | friend void file_scope_friend(); |
348 | }; |
349 | return A(); |
350 | } |
351 | |
352 | void file_scope_friend() { |
353 | auto a = friend_file_func(); |
354 | (void)a.p; |
355 | } |
356 | } |
357 | |
358 | template<typename T> |
359 | struct X_pr6954 { |
360 | operator int(); |
361 | friend void f_pr6954(int x); |
362 | }; |
363 | |
364 | int array0_pr6954[sizeof(X_pr6954<int>)]; |
365 | int array1_pr6954[sizeof(X_pr6954<float>)]; |
366 | |
367 | void g_pr6954() { |
368 | f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}} |
369 | } |
370 | |
371 | namespace tag_redecl { |
372 | namespace N { |
373 | struct X *p; |
374 | namespace { |
375 | class K { |
376 | friend struct X; |
377 | }; |
378 | } |
379 | } |
380 | namespace N { |
381 | struct X; |
382 | X *q = p; |
383 | } |
384 | } |
385 | |
386 | namespace default_arg { |
387 | void f(); |
388 | void f(void*); // expected-note {{previous}} |
389 | struct X { |
390 | friend void f(int a, int b = 0) {} |
391 | friend void f(void *p = 0) {} // expected-error {{must be the only}} |
392 | }; |
393 | } |
394 | |
395 | namespace PR33222 { |
396 | int f(); |
397 | template<typename T> struct X { |
398 | friend T f(); |
399 | }; |
400 | X<int> xi; |
401 | |
402 | int g(); // expected-note {{previous}} |
403 | template<typename T> struct Y { |
404 | friend T g(); // expected-error {{return type}} |
405 | }; |
406 | Y<float> yf; // expected-note {{instantiation}} |
407 | |
408 | int h(); // expected-note {{previous}} |
409 | template<typename T> struct Z { |
410 | friend T h(); // expected-error {{return type}} |
411 | }; |
412 | Z<int> zi; |
413 | Z<float> zf; // expected-note {{instantiation}} |
414 | } |
415 | |
416 | namespace qualified_friend_no_match { |
417 | void f(int); // expected-note {{type mismatch at 1st parameter}} |
418 | template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}} |
419 | struct X { |
420 | friend void qualified_friend_no_match::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}} |
421 | friend void qualified_friend_no_match::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}} |
422 | }; |
423 | |
424 | struct Y { |
425 | void f(int); // expected-note {{type mismatch at 1st parameter}} |
426 | template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}} |
427 | }; |
428 | struct Z { |
429 | friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}} |
430 | }; |
431 | } |
432 | |