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