1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
2
3 friend class A; // expected-error {{'friend' used outside of class}}
f()4 void f() { friend class A; } // expected-error {{'friend' used outside of class}}
5 class C { friend class A; };
f()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
test()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 {
getInt(int inInt=0)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;
A()89 A() {}
90 };
91 class vectorA {
92 public:
vectorA(int i,const A & t=A ())93 vectorA(int i, const A& t = A()) {}
94 };
f()95 void f() {
96 vectorA v(1);
97 }
98 }
99 namespace test6_2 {
100 template<class T>
101 class vector {
102 public:
vector(int i,const T & t=T ())103 vector(int i, const T& t = T()) {}
104 };
105 class A {
106 public:
107 private:
108 friend class vector<A>;
A()109 A() {}
110 };
f()111 void f() {
112 vector<A> v(1);
113 }
114 }
115 namespace test6_3 {
116 template<class T>
117 class vector {
118 public:
vector(int i)119 vector(int i) {}
f(const T & t=T ())120 void f(const T& t = T()) {}
121 };
122 class A {
123 public:
124 private:
125 friend void vector<A>::f(const A&);
A()126 A() {}
127 };
f()128 void f() {
129 vector<A> v(1);
130 v.f();
131 }
132 }
133
134 namespace test7 {
135 extern "C" {
136 class X {
test7_f()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 {
ftest9::A165 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.
g(X x)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
g(X x,Y y,Z z)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
local_externs(W w,X x,Y y)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
i(X x,Y y)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
j(X x,Y y)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);
k(X x,Y y,Z z)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
friend_own_method()313 void friend_own_method() {
314 class A {
315 void m() {}
316 friend void m();
317 };
318 }
319
friend_enclosing_method()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
friend_file_func()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
file_scope_friend()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
g_pr6954()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 {
f(int a,int b=0)390 friend void f(int a, int b = 0) {}
f(void * p=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