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 {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}}
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
g(X x,Y y,Z z)233 void g(X x, Y y, Z z) {
234 f10_d(); // expected-error {{undeclared identifier}}
235 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
236
237 // f10_d is visible to ADL in the second and third cases.
238 f10_d(x); // expected-error {{undeclared identifier}}
239 f10_d(y);
240 f10_d(z);
241
242 // No ADL here.
243 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
244 ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
245 ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
246 }
247
local_externs(X x,Y y)248 void local_externs(X x, Y y) {
249 extern void f10_d();
250 extern void f10_d(X);
251 f10_d();
252 f10_d(x);
253 // FIXME: This lookup should fail, because the local extern declaration
254 // should suppress ADL.
255 f10_d(y);
256 {
257 int f10_d;
258 f10_d(); // expected-error {{not a function}}
259 f10_d(x); // expected-error {{not a function}}
260 f10_d(y); // expected-error {{not a function}}
261 }
262 }
263
i(X x,Y y)264 void i(X x, Y y) {
265 f10_d(); // expected-error {{undeclared identifier}}
266 f10_d(x); // expected-error {{undeclared identifier}}
267 f10_d(y);
268 }
269
270 struct C {
271 friend void f10_d();
272 friend void f10_d(X);
273 };
274
j(X x,Y y)275 void j(X x, Y y) {
276 f10_d(); // expected-error {{undeclared identifier}}
277 f10_d(x); // expected-error {{undeclared identifier}}
278 f10_d(y);
279 }
280
281 extern void f10_d();
282 extern void f10_d(X);
k(X x,Y y,Z z)283 void k(X x, Y y, Z z) {
284 // All OK now.
285 f10_d();
286 f10_d(x);
287 ::test10::f10_d();
288 ::test10::f10_d(x);
289 ::test10::f10_d(y);
290 ::test10::f10_d(z);
291 }
292 }
293
294 namespace test11 {
295 class __attribute__((visibility("hidden"))) B;
296
297 class A {
298 friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
299 };
300 }
301
302 namespace pr21851 {
303 // PR21851 was a problem where we assumed that when the friend function redecl
304 // lookup found a C++ method, it would necessarily have a qualifier. Below we
305 // have some test cases where unqualified lookup finds C++ methods without using
306 // qualifiers. Unfortunately, we can't exercise the case of an access check
307 // failure because nested classes always have access to the members of outer
308 // classes.
309
friend_own_method()310 void friend_own_method() {
311 class A {
312 void m() {}
313 friend void m();
314 };
315 }
316
friend_enclosing_method()317 void friend_enclosing_method() {
318 class A;
319 class C {
320 int p;
321 friend class A;
322 };
323 class A {
324 void enclosing_friend() {
325 (void)b->p;
326 (void)c->p;
327 }
328 class B {
329 void b(A *a) {
330 (void)a->c->p;
331 }
332 int p;
333 friend void enclosing_friend();
334 };
335 B *b;
336 C *c;
337 };
338 }
339
friend_file_func()340 static auto friend_file_func() {
341 extern void file_scope_friend();
342 class A {
343 int p;
344 friend void file_scope_friend();
345 };
346 return A();
347 }
348
file_scope_friend()349 void file_scope_friend() {
350 auto a = friend_file_func();
351 (void)a.p;
352 }
353 }
354
355 template<typename T>
356 struct X_pr6954 {
357 operator int();
358 friend void f_pr6954(int x);
359 };
360
361 int array0_pr6954[sizeof(X_pr6954<int>)];
362 int array1_pr6954[sizeof(X_pr6954<float>)];
363
g_pr6954()364 void g_pr6954() {
365 f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
366 }
367
368 namespace tag_redecl {
369 namespace N {
370 struct X *p;
371 namespace {
372 class K {
373 friend struct X;
374 };
375 }
376 }
377 namespace N {
378 struct X;
379 X *q = p;
380 }
381 }
382