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 {{target of using declaration}}
151 struct B : public A { using A::f; }; // expected-note {{using declaration}}
152 struct X {
153 template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}}
154 friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
155 };
156 }
157
158 // PR16423
159 namespace test9 {
160 class C {
161 };
162 struct A {
ftest9::A163 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}}
164 };
165 }
166
167 namespace test10 {
168 struct X {};
169 extern void f10_a();
170 extern void f10_a(X);
171 struct A {
172 friend void f10_a();
173 friend void f10_b();
174 friend void f10_c();
175 friend void f10_d();
176 friend void f10_a(X);
177 friend void f10_b(X);
178 friend void f10_c(X);
179 friend void f10_d(X);
180 };
181 extern void f10_b();
182 extern void f10_b(X);
183 struct B {
184 friend void f10_a();
185 friend void f10_b();
186 friend void f10_c();
187 friend void f10_d();
188 friend void f10_a(X);
189 friend void f10_b(X);
190 friend void f10_c(X);
191 friend void f10_d(X);
192 };
193 extern void f10_c();
194 extern void f10_c(X);
195
196 // FIXME: Give a better diagnostic for the case where a function exists but is
197 // not visible.
g(X x)198 void g(X x) {
199 f10_a();
200 f10_b();
201 f10_c();
202 f10_d(); // expected-error {{undeclared identifier}}
203
204 ::test10::f10_a();
205 ::test10::f10_b();
206 ::test10::f10_c();
207 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
208
209 f10_a(x);
210 f10_b(x);
211 f10_c(x);
212 f10_d(x); // PR16597: expected-error {{undeclared identifier}}
213
214 ::test10::f10_a(x);
215 ::test10::f10_b(x);
216 ::test10::f10_c(x);
217 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
218 }
219
220 struct Y : X {
221 friend void f10_d();
222 friend void f10_d(X);
223 };
224
225 struct Z {
226 operator X();
227 friend void f10_d();
228 friend void f10_d(X);
229 };
230
g(X x,Y y,Z z)231 void g(X x, Y y, Z z) {
232 f10_d(); // expected-error {{undeclared identifier}}
233 ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
234
235 // f10_d is visible to ADL in the second and third cases.
236 f10_d(x); // expected-error {{undeclared identifier}}
237 f10_d(y);
238 f10_d(z);
239
240 // No ADL here.
241 ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
242 ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
243 ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
244 }
245
local_externs(X x,Y y)246 void local_externs(X x, Y y) {
247 extern void f10_d();
248 extern void f10_d(X);
249 f10_d();
250 f10_d(x);
251 // FIXME: This lookup should fail, because the local extern declaration
252 // should suppress ADL.
253 f10_d(y);
254 {
255 int f10_d;
256 f10_d(); // expected-error {{not a function}}
257 f10_d(x); // expected-error {{not a function}}
258 f10_d(y); // expected-error {{not a function}}
259 }
260 }
261
i(X x,Y y)262 void i(X x, Y y) {
263 f10_d(); // expected-error {{undeclared identifier}}
264 f10_d(x); // expected-error {{undeclared identifier}}
265 f10_d(y);
266 }
267
268 struct C {
269 friend void f10_d();
270 friend void f10_d(X);
271 };
272
j(X x,Y y)273 void j(X x, Y y) {
274 f10_d(); // expected-error {{undeclared identifier}}
275 f10_d(x); // expected-error {{undeclared identifier}}
276 f10_d(y);
277 }
278
279 extern void f10_d();
280 extern void f10_d(X);
k(X x,Y y,Z z)281 void k(X x, Y y, Z z) {
282 // All OK now.
283 f10_d();
284 f10_d(x);
285 ::test10::f10_d();
286 ::test10::f10_d(x);
287 ::test10::f10_d(y);
288 ::test10::f10_d(z);
289 }
290 }
291
292 namespace test11 {
293 class __attribute__((visibility("hidden"))) B;
294
295 class A {
296 friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
297 };
298 }
299
300 namespace pr21851 {
301 // PR21851 was a problem where we assumed that when the friend function redecl
302 // lookup found a C++ method, it would necessarily have a qualifier. Below we
303 // have some test cases where unqualified lookup finds C++ methods without using
304 // qualifiers. Unfortunately, we can't exercise the case of an access check
305 // failure because nested classes always have access to the members of outer
306 // classes.
307
friend_own_method()308 void friend_own_method() {
309 class A {
310 void m() {}
311 friend void m();
312 };
313 }
314
friend_enclosing_method()315 void friend_enclosing_method() {
316 class A;
317 class C {
318 int p;
319 friend class A;
320 };
321 class A {
322 void enclosing_friend() {
323 (void)b->p;
324 (void)c->p;
325 }
326 class B {
327 void b(A *a) {
328 (void)a->c->p;
329 }
330 int p;
331 friend void enclosing_friend();
332 };
333 B *b;
334 C *c;
335 };
336 }
337
friend_file_func()338 static auto friend_file_func() {
339 extern void file_scope_friend();
340 class A {
341 int p;
342 friend void file_scope_friend();
343 };
344 return A();
345 }
346
file_scope_friend()347 void file_scope_friend() {
348 auto a = friend_file_func();
349 (void)a.p;
350 }
351 }
352
353 template<typename T>
354 struct X_pr6954 {
355 operator int();
356 friend void f_pr6954(int x);
357 };
358
359 int array0_pr6954[sizeof(X_pr6954<int>)];
360 int array1_pr6954[sizeof(X_pr6954<float>)];
361
g_pr6954()362 void g_pr6954() {
363 f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
364 }
365
366