1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 |
2 | |
3 | // If a friend function is defined in several non-template classes, |
4 | // it is an error. |
5 | |
6 | void func1(int); |
7 | struct C1a { |
8 | friend void func1(int) {} // expected-note{{previous definition is here}} |
9 | }; |
10 | struct C1b { |
11 | friend void func1(int) {} // expected-error{{redefinition of 'func1'}} |
12 | }; |
13 | |
14 | |
15 | // If a friend function is defined in both non-template and template |
16 | // classes it is an error only if the template is instantiated. |
17 | |
18 | void func2(int); |
19 | struct C2a { |
20 | friend void func2(int) {} |
21 | }; |
22 | template<typename T> struct C2b { |
23 | friend void func2(int) {} |
24 | }; |
25 | |
26 | void func3(int); |
27 | struct C3a { |
28 | friend void func3(int) {} // expected-note{{previous definition is here}} |
29 | }; |
30 | template<typename T> struct C3b { |
31 | friend void func3(int) {} // expected-error{{redefinition of 'func3'}} |
32 | }; |
33 | C3b<long> c3; // expected-note{{in instantiation of template class 'C3b<long>' requested here}} |
34 | |
35 | |
36 | // If a friend function is defined in several template classes it is an error |
37 | // only if several templates are instantiated. |
38 | |
39 | void func4(int); |
40 | template<typename T> struct C4a { |
41 | friend void func4(int) {} |
42 | }; |
43 | template<typename T> struct C4b { |
44 | friend void func4(int) {} |
45 | }; |
46 | |
47 | |
48 | void func5(int); |
49 | template<typename T> struct C5a { |
50 | friend void func5(int) {} |
51 | }; |
52 | template<typename T> struct C5b { |
53 | friend void func5(int) {} |
54 | }; |
55 | C5a<long> c5a; |
56 | |
57 | void func6(int); |
58 | template<typename T> struct C6a { |
59 | friend void func6(int) {} // expected-note{{previous definition is here}} |
60 | }; |
61 | template<typename T> struct C6b { |
62 | friend void func6(int) {} // expected-error{{redefinition of 'func6'}} |
63 | }; |
64 | C6a<long> c6a; |
65 | C6b<int*> c6b; // expected-note{{in instantiation of template class 'C6b<int *>' requested here}} |
66 | |
67 | void func7(int); |
68 | template<typename T> struct C7 { |
69 | friend void func7(int) {} // expected-error{{redefinition of 'func7'}} |
70 | // expected-note@-1{{previous definition is here}} |
71 | }; |
72 | C7<long> c7a; |
73 | C7<int*> c7b; // expected-note{{in instantiation of template class 'C7<int *>' requested here}} |
74 | |
75 | |
76 | // Even if clases are not instantiated and hence friend functions defined in them are not |
77 | // available, their declarations can be checked. |
78 | |
79 | void func8(int); // expected-note{{previous declaration is here}} |
80 | template<typename T> struct C8a { |
81 | friend long func8(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} |
82 | }; |
83 | |
84 | void func9(int); // expected-note{{previous declaration is here}} |
85 | template<typename T> struct C9a { |
86 | friend int func9(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} |
87 | }; |
88 | |
89 | void func10(int); // expected-note{{previous declaration is here}} |
90 | template<typename T> struct C10a { |
91 | friend int func10(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} |
92 | }; |
93 | |
94 | void func_11(); // expected-note{{previous declaration is here}} |
95 | template<typename T> class C11 { |
96 | friend int func_11(); // expected-error{{functions that differ only in their return type cannot be overloaded}} |
97 | }; |
98 | |
99 | void func_12(int x); // expected-note{{previous declaration is here}} |
100 | template<typename T> class C12 { |
101 | friend void func_12(int x = 0); // expected-error{{friend declaration specifying a default argument must be the only declaration}} |
102 | }; |
103 | |
104 | // Friend function with uninstantiated body is still a definition. |
105 | |
106 | template<typename T> struct C20 { |
107 | friend void func_20() {} // expected-note{{previous definition is here}} |
108 | }; |
109 | C20<int> c20i; |
110 | void func_20() {} // expected-error{{redefinition of 'func_20'}} |
111 | |
112 | template<typename T> struct C21a { |
113 | friend void func_21() {} // expected-note{{previous definition is here}} |
114 | }; |
115 | template<typename T> struct C21b { |
116 | friend void func_21() {} // expected-error{{redefinition of 'func_21'}} |
117 | }; |
118 | C21a<int> c21ai; |
119 | C21b<int> c21bi; // expected-note{{in instantiation of template class 'C21b<int>' requested here}} |
120 | |
121 | template<typename T> struct C22a { |
122 | friend void func_22() {} // expected-note{{previous definition is here}} |
123 | }; |
124 | template<typename T> struct C22b { |
125 | friend void func_22(); |
126 | }; |
127 | C22a<int> c22ai; |
128 | C22b<int> c22bi; |
129 | void func_22() {} // expected-error{{redefinition of 'func_22'}} |
130 | |
131 | |
132 | // Case of template friend functions. |
133 | |
134 | template<typename T> void func_31(T *x); |
135 | template<typename T1> |
136 | struct C31a { |
137 | template<typename T> friend void func_31(T *x) {} |
138 | }; |
139 | template<typename T1> |
140 | struct C31b { |
141 | template<typename T> friend void func_31(T *x) {} |
142 | }; |
143 | |
144 | |
145 | template<typename T> inline void func_32(T *x) {} |
146 | template<typename T1> |
147 | struct C32a { |
148 | template<typename T> friend void func_32(T *x) {} |
149 | }; |
150 | template<typename T1> |
151 | struct C32b { |
152 | template<typename T> friend void func_32(T *x) {} |
153 | }; |
154 | |
155 | |
156 | template<typename T1> |
157 | struct C33a { |
158 | template<typename T> friend void func_33(T *x) {} |
159 | }; |
160 | template<typename T1> |
161 | struct C33b { |
162 | template<typename T> friend void func_33(T *x) {} |
163 | }; |
164 | |
165 | |
166 | template<typename T> inline void func_34(T *x) {} // expected-note{{previous definition is here}} |
167 | template<typename T1> |
168 | struct C34 { |
169 | template<typename T> friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}} |
170 | }; |
171 | |
172 | C34<int> v34; // expected-note{{in instantiation of template class 'C34<int>' requested here}} |
173 | |
174 | |
175 | template<typename T> inline void func_35(T *x); |
176 | template<typename T1> |
177 | struct C35a { |
178 | template<typename T> friend void func_35(T *x) {} // expected-note{{previous definition is here}} |
179 | }; |
180 | template<typename T1> |
181 | struct C35b { |
182 | template<typename T> friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}} |
183 | }; |
184 | |
185 | C35a<int> v35a; |
186 | C35b<int> v35b; // expected-note{{in instantiation of template class 'C35b<int>' requested here}} |
187 | |
188 | |
189 | template<typename T> void func_36(T *x); |
190 | template<typename T1> |
191 | struct C36 { |
192 | template<typename T> friend void func_36(T *x) {} // expected-error{{redefinition of 'func_36'}} |
193 | // expected-note@-1{{previous definition is here}} |
194 | }; |
195 | |
196 | C36<int> v36a; |
197 | C36<long> v36b; //expected-note{{in instantiation of template class 'C36<long>' requested here}} |
198 | |
199 | |
200 | template<typename T> void func_37(T *x); |
201 | template<typename T1> |
202 | struct C37 { |
203 | template<typename T> friend void func_37(T *x) {} // expected-note{{previous definition is here}} |
204 | }; |
205 | |
206 | C37<int> v37; |
207 | template<typename T> void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}} |
208 | |
209 | |
210 | namespace pr22307 { |
211 | |
212 | struct t { |
213 | friend int leak(t); |
214 | }; |
215 | |
216 | template<typename v> |
217 | struct m { |
218 | friend int leak(t) { return sizeof(v); } // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}} |
219 | }; |
220 | |
221 | template struct m<char>; |
222 | template struct m<short>; // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}} |
223 | |
224 | int main() { |
225 | leak(t()); |
226 | } |
227 | |
228 | } |
229 | |
230 | namespace pr17923 { |
231 | |
232 | void f(unsigned long long); |
233 | |
234 | template<typename T> struct X { |
235 | friend void f(unsigned long long) { |
236 | T t; |
237 | } |
238 | }; |
239 | |
240 | int main() { f(1234); } |
241 | |
242 | } |
243 | |
244 | namespace pr17923a { |
245 | |
246 | int get(); |
247 | |
248 | template< int value > |
249 | class set { |
250 | friend int get() |
251 | { return value; } // return 0; is OK |
252 | }; |
253 | |
254 | template class set< 5 >; |
255 | |
256 | int main() { |
257 | get(); |
258 | } |
259 | |
260 | } |
261 | |
262 | namespace pr8035 { |
263 | |
264 | void Function(); |
265 | |
266 | int main(int argc, char* argv[]) { |
267 | Function(); |
268 | } |
269 | |
270 | template <typename T> |
271 | struct Test { |
272 | friend void Function() { } |
273 | }; |
274 | |
275 | template class Test<int>; |
276 | |
277 | } |
278 | |
279 | namespace pr14785 { |
280 | template<typename T> |
281 | struct Somewhat { |
282 | void internal() const { } |
283 | friend void operator+(int const &, Somewhat<T> const &) {} // expected-error{{redefinition of 'operator+'}} |
284 | }; |
285 | |
286 | void operator+(int const &, Somewhat<char> const &x) { // expected-note {{previous definition is here}} |
287 | x.internal(); // expected-note{{in instantiation of template class 'pr14785::Somewhat<char>' requested here}} |
288 | } |
289 | } |
290 | |
291 | namespace D30375 { |
292 | template <typename K> struct B { |
293 | template <typename A> bool insert(A &); |
294 | }; |
295 | |
296 | template <typename K> |
297 | template <typename A> bool B<K>::insert(A &x) { return x < x; } |
298 | |
299 | template <typename K> class D { |
300 | B<K> t; |
301 | |
302 | public: |
303 | K x; |
304 | bool insert() { return t.insert(x); } |
305 | template <typename K1> friend bool operator<(const D<K1> &, const D<K1> &); |
306 | }; |
307 | |
308 | template <typename K> bool operator<(const D<K> &, const D<K> &); |
309 | |
310 | void func() { |
311 | D<D<int>> cache; |
312 | cache.insert(); |
313 | } |
314 | } |
315 | |
316 | namespace PR39742 { |
317 | template<typename> |
318 | struct wrapper { |
319 | template<typename> |
320 | friend void friend_function_template() {} // expected-error{{redefinition of 'friend_function_template'}} |
321 | // expected-note@-1{{previous definition is here}} |
322 | }; |
323 | |
324 | wrapper<bool> x; |
325 | wrapper<int> y; // expected-note{{in instantiation of template class 'PR39742::wrapper<int>' requested here}} |
326 | } |
327 | |