Clang Project

clang_source_code/test/SemaCXX/friend2.cpp
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
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
104// 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
132// 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
209
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}
278
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}
315
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}
327