blob: 1ed751b4f36150f2e74801b0900d743000ef4fed [file] [log] [blame]
Yaron Keren27e2ff92017-04-17 08:51:20 +00001// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
Douglas Gregor3dad8422009-09-26 06:47:28 +00002// PR5057
John McCalld53cee12009-12-11 20:51:23 +00003namespace test0 {
4 namespace std {
5 class X {
6 public:
7 template<typename T> friend struct Y;
8 };
9 }
10
11 namespace std {
12 template<typename T> struct Y {};
13 }
Douglas Gregor3dad8422009-09-26 06:47:28 +000014}
15
John McCalld53cee12009-12-11 20:51:23 +000016namespace test1 {
Douglas Gregora29a3ff2009-09-28 00:08:27 +000017 template<typename T> void f1(T) { } // expected-note{{here}}
18
19 class X {
20 template<typename T> friend void f0(T);
21 template<typename T> friend void f1(T);
22 };
23
24 template<typename T> void f0(T) { }
25 template<typename T> void f1(T) { } // expected-error{{redefinition}}
26}
Douglas Gregor7f34bae2009-10-09 21:11:42 +000027
28// PR4768
John McCalld53cee12009-12-11 20:51:23 +000029namespace test2 {
30 template<typename T> struct X0 {
31 template<typename U> friend struct X0;
32 };
33
34 template<typename T> struct X0<T*> {
35 template<typename U> friend struct X0;
36 };
Douglas Gregor7f34bae2009-10-09 21:11:42 +000037
John McCalld53cee12009-12-11 20:51:23 +000038 template<> struct X0<int> {
39 template<typename U> friend struct X0;
40 };
Douglas Gregor7f34bae2009-10-09 21:11:42 +000041
John McCalld53cee12009-12-11 20:51:23 +000042 template<typename T> struct X1 {
43 template<typename U> friend void f2(U);
44 template<typename U> friend void f3(U);
45 };
Douglas Gregor3a88c1d2009-10-13 14:39:41 +000046
John McCalld53cee12009-12-11 20:51:23 +000047 template<typename U> void f2(U);
Douglas Gregor3a88c1d2009-10-13 14:39:41 +000048
John McCalld53cee12009-12-11 20:51:23 +000049 X1<int> x1i;
50 X0<int*> x0ip;
Douglas Gregor3a88c1d2009-10-13 14:39:41 +000051
John McCalld53cee12009-12-11 20:51:23 +000052 template<> void f2(int);
Douglas Gregor3a88c1d2009-10-13 14:39:41 +000053
John McCalld53cee12009-12-11 20:51:23 +000054 // FIXME: Should this declaration of f3 be required for the specialization of
55 // f3<int> (further below) to work? GCC and EDG don't require it, we do...
56 template<typename U> void f3(U);
Douglas Gregor3a88c1d2009-10-13 14:39:41 +000057
John McCalld53cee12009-12-11 20:51:23 +000058 template<> void f3(int);
59}
Douglas Gregor412e8bc2009-10-30 21:07:27 +000060
61// PR5332
John McCalld53cee12009-12-11 20:51:23 +000062namespace test3 {
63 template <typename T> class Foo {
64 template <typename U>
65 friend class Foo;
66 };
Douglas Gregor412e8bc2009-10-30 21:07:27 +000067
John McCalld53cee12009-12-11 20:51:23 +000068 Foo<int> foo;
Douglas Gregorbb3b46e2009-10-30 22:42:42 +000069
John McCalld53cee12009-12-11 20:51:23 +000070 template<typename T, T Value> struct X2a;
Yaron Keren27e2ff92017-04-17 08:51:20 +000071 template<typename T, int Size> struct X2b; // expected-note {{previous non-type template parameter with type 'int' is here}}
Douglas Gregorbb3b46e2009-10-30 22:42:42 +000072
John McCalld53cee12009-12-11 20:51:23 +000073 template<typename T>
74 class X3 {
75 template<typename U, U Value> friend struct X2a;
Yaron Keren27e2ff92017-04-17 08:51:20 +000076 template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}}
John McCalld53cee12009-12-11 20:51:23 +000077 };
Douglas Gregorbb3b46e2009-10-30 22:42:42 +000078
John McCalld53cee12009-12-11 20:51:23 +000079 X3<int> x3i; // okay
Douglas Gregorbb3b46e2009-10-30 22:42:42 +000080
John McCall598b4402010-03-25 06:39:04 +000081 X3<long> x3l; // expected-note {{in instantiation}}
John McCalld53cee12009-12-11 20:51:23 +000082}
John McCall2079d0b2009-12-14 23:19:40 +000083
84// PR5716
85namespace test4 {
86 template<typename> struct A {
87 template<typename T> friend void f(const A<T>&);
88 };
89
90 template<typename T> void f(const A<T>&) {
Chandler Carrutha92409c2011-01-04 04:44:35 +000091 int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
John McCall2079d0b2009-12-14 23:19:40 +000092 }
93
94 void f() {
95 f(A<int>()); // expected-note {{in instantiation of function template specialization}}
96 }
97}
John McCalld43784f2009-12-18 11:25:59 +000098
99namespace test5 {
100 class outer {
101 class foo;
102 template <typename T> friend struct cache;
103 };
104 class outer::foo {
105 template <typename T> friend struct cache;
106 };
107}
Douglas Gregore1ad8a12010-01-16 18:09:52 +0000108
109// PR6022
110namespace PR6022 {
111 template <class T1, class T2 , class T3 > class A;
112
113 namespace inner {
114 template<class T1, class T2, class T3, class T>
115 A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
116 }
117
118 template<class T1, class T2, class T3>
119 class A {
120 template<class U1, class U2, class U3, class T>
121 friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
122 };
123}
124
Douglas Gregor16142372010-04-28 04:52:24 +0000125namespace FriendTemplateDefinition {
126 template<unsigned > struct int_c { };
127
128 template<typename T>
129 struct X {
130 template<unsigned N>
131 friend void f(X, int_c<N>) {
132 int value = N;
133 };
134 };
135
136 void test_X(X<int> x, int_c<5> i5) {
137 f(x, i5);
138 }
139}
Douglas Gregor1bd7a942010-05-03 23:29:10 +0000140
141namespace PR7013a {
142 template<class > struct X0
143 {
144 typedef int type;
145 };
146 template<typename > struct X1
147 {
148 };
149 template<typename , typename T> struct X2
150 {
151 typename T::type e;
152 };
153 namespace N
154 {
155 template <typename = int, typename = X1<int> > struct X3
156 {
157 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
158 };
159 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
160 {
161 X2<int, Tr> s;
162 }
163 }
164 int n()
165 {
166 X2<int, X0<int> > ngs;
167 N::X3<> b;
168 op(ngs, b);
169 return 0;
170 }
171}
172
173namespace PR7013b {
174 template<class > struct X0
175 {
176 typedef int type;
177 };
178 template<typename > struct X1
179 {
180 };
181 template<typename , typename T> struct X2
182 {
183 typename T::type e;
184 };
185 namespace N
186 {
187 template <typename = X1<int> > struct X3
188 {
189 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
190 };
191 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
192 {
193 X2<int, Tr> s;
194 }
195 }
196 int n()
197 {
198 X2<int, X0<int> > ngs;
199 N::X3<> b;
200 op(ngs, b);
201 return 0;
202 }
203
204}
Douglas Gregorec9518b2010-12-21 08:14:57 +0000205
206namespace PR8649 {
207 template<typename T, typename U, unsigned N>
208 struct X {
209 template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}}
210 };
211
212 X<int, float, 7> x;
213}
Chandler Carruth7c9856d2011-05-03 18:35:10 +0000214
215// Don't crash, and error on invalid friend type template.
216namespace friend_type_template_no_tag {
217 template <typename T> struct S {
218 template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
219 };
220 template struct S<int>;
221}
Douglas Gregorf65d8ff2011-10-20 15:58:54 +0000222
223namespace PR10660 {
224 struct A {
225 template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
226 };
227}
Douglas Gregor67daacb2012-03-30 16:20:47 +0000228
229namespace rdar11147355 {
Richard Smithcd556eb2013-11-08 18:59:56 +0000230 template <class T>
Douglas Gregor67daacb2012-03-30 16:20:47 +0000231 struct A {
232 template <class U> class B;
Richard Smithcd556eb2013-11-08 18:59:56 +0000233 template <class S> template <class U> friend class A<S>::B; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}}
234 private:
235 int n; // expected-note {{here}}
Douglas Gregor67daacb2012-03-30 16:20:47 +0000236 };
Richard Smithcd556eb2013-11-08 18:59:56 +0000237
Douglas Gregor67daacb2012-03-30 16:20:47 +0000238 template <class S> template <class U> class A<S>::B {
Richard Smithcd556eb2013-11-08 18:59:56 +0000239 public:
240 // FIXME: This should be permitted.
241 int f(A<S*> a) { return a.n; } // expected-error {{private}}
242 };
243
Douglas Gregor67daacb2012-03-30 16:20:47 +0000244 A<double>::B<double> ab;
Richard Smithcd556eb2013-11-08 18:59:56 +0000245 A<double*> a;
246 int k = ab.f(a); // expected-note {{instantiation of}}
Douglas Gregor67daacb2012-03-30 16:20:47 +0000247}
Richard Smith61e582f2012-04-20 07:12:26 +0000248
249namespace RedeclUnrelated {
250 struct S {
251 int packaged_task;
252 template<typename> class future {
253 template<typename> friend class packaged_task;
254 };
255 future<void> share;
256 };
257}
258
259namespace PR12557 {
260 template <typename>
261 struct Foo;
262
263 template <typename Foo_>
264 struct Bar {
265 typedef Foo_ Foo; // expected-note {{previous}}
266
267 template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
268 };
269
270 Bar<int> b;
271}
Richard Smithe85e1762012-04-22 02:13:50 +0000272
273namespace PR12585 {
274 struct A { };
275 template<typename> struct B {
276 template<typename> friend class A::does_not_exist; // \
277 // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
278 };
279
280 struct C {
281 template<typename> struct D;
282 };
283 template<typename> class E {
284 int n;
285 template<typename> friend struct C::D;
286 };
287 template<typename T> struct C::D {
288 int f() {
289 return E<int>().n;
290 }
291 };
292 int n = C::D<void*>().f();
293
294 struct F {
Yaron Keren27e2ff92017-04-17 08:51:20 +0000295 template<int> struct G; // expected-note {{previous}}
Richard Smithe85e1762012-04-22 02:13:50 +0000296 };
297 template<typename T> struct H {
Richard Smithe85e1762012-04-22 02:13:50 +0000298 template<T> friend struct F::G; // \
Yaron Keren27e2ff92017-04-17 08:51:20 +0000299 // expected-error {{different type 'char' in template redeclaration}}
Richard Smithe85e1762012-04-22 02:13:50 +0000300 };
301 H<int> h1; // ok
302 H<char> h2; // expected-note {{instantiation}}
303}
John McCalle68672f2013-03-14 05:13:41 +0000304
305// Ensure that we can still instantiate a friend function template
306// after the friend declaration is instantiated during the delayed
307// parsing of a member function, but before the friend function has
308// been parsed.
309namespace rdar12350696 {
310 template <class T> struct A {
311 void foo() {
312 A<int> a;
313 }
314 template <class U> friend void foo(const A<U> & a) {
315 int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
316 }
317 };
318
319 void test() {
320 A<int> b;
321 foo(b); // expected-note {{in instantiation}}
322 }
323}
Yaron Keren27e2ff92017-04-17 08:51:20 +0000324namespace PR30994 {
325 void f();
326 struct A {
327 [[deprecated]] friend void f() {} // \
328 expected-note {{has been explicitly marked deprecated here}}
329 };
330 void g() { f(); } // expected-warning {{is deprecated}}
331}