106b7a872SSerge Pavlov // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
206b7a872SSerge Pavlov
306b7a872SSerge Pavlov // If a friend function is defined in several non-template classes,
406b7a872SSerge Pavlov // it is an error.
506b7a872SSerge Pavlov
606b7a872SSerge Pavlov void func1(int);
706b7a872SSerge Pavlov struct C1a {
func1(int)806b7a872SSerge Pavlov friend void func1(int) {} // expected-note{{previous definition is here}}
906b7a872SSerge Pavlov };
1006b7a872SSerge Pavlov struct C1b {
func1(int)1106b7a872SSerge Pavlov friend void func1(int) {} // expected-error{{redefinition of 'func1'}}
1206b7a872SSerge Pavlov };
1306b7a872SSerge Pavlov
1406b7a872SSerge Pavlov
1506b7a872SSerge Pavlov // If a friend function is defined in both non-template and template
1606b7a872SSerge Pavlov // classes it is an error only if the template is instantiated.
1706b7a872SSerge Pavlov
1806b7a872SSerge Pavlov void func2(int);
1906b7a872SSerge Pavlov struct C2a {
func2(int)2006b7a872SSerge Pavlov friend void func2(int) {}
2106b7a872SSerge Pavlov };
2206b7a872SSerge Pavlov template<typename T> struct C2b {
func2(int)2306b7a872SSerge Pavlov friend void func2(int) {}
2406b7a872SSerge Pavlov };
2506b7a872SSerge Pavlov
2606b7a872SSerge Pavlov void func3(int);
2706b7a872SSerge Pavlov struct C3a {
func3(int)2806b7a872SSerge Pavlov friend void func3(int) {} // expected-note{{previous definition is here}}
2906b7a872SSerge Pavlov };
3006b7a872SSerge Pavlov template<typename T> struct C3b {
func3(int)3106b7a872SSerge Pavlov friend void func3(int) {} // expected-error{{redefinition of 'func3'}}
3206b7a872SSerge Pavlov };
3306b7a872SSerge Pavlov C3b<long> c3; // expected-note{{in instantiation of template class 'C3b<long>' requested here}}
3406b7a872SSerge Pavlov
3506b7a872SSerge Pavlov
3606b7a872SSerge Pavlov // If a friend function is defined in several template classes it is an error
3706b7a872SSerge Pavlov // only if several templates are instantiated.
3806b7a872SSerge Pavlov
3906b7a872SSerge Pavlov void func4(int);
4006b7a872SSerge Pavlov template<typename T> struct C4a {
func4(int)4106b7a872SSerge Pavlov friend void func4(int) {}
4206b7a872SSerge Pavlov };
4306b7a872SSerge Pavlov template<typename T> struct C4b {
func4(int)4406b7a872SSerge Pavlov friend void func4(int) {}
4506b7a872SSerge Pavlov };
4606b7a872SSerge Pavlov
4706b7a872SSerge Pavlov
4806b7a872SSerge Pavlov void func5(int);
4906b7a872SSerge Pavlov template<typename T> struct C5a {
func5(int)5006b7a872SSerge Pavlov friend void func5(int) {}
5106b7a872SSerge Pavlov };
5206b7a872SSerge Pavlov template<typename T> struct C5b {
func5(int)5306b7a872SSerge Pavlov friend void func5(int) {}
5406b7a872SSerge Pavlov };
5506b7a872SSerge Pavlov C5a<long> c5a;
5606b7a872SSerge Pavlov
5706b7a872SSerge Pavlov void func6(int);
5806b7a872SSerge Pavlov template<typename T> struct C6a {
func6(int)5906b7a872SSerge Pavlov friend void func6(int) {} // expected-note{{previous definition is here}}
6006b7a872SSerge Pavlov };
6106b7a872SSerge Pavlov template<typename T> struct C6b {
func6(int)6206b7a872SSerge Pavlov friend void func6(int) {} // expected-error{{redefinition of 'func6'}}
6306b7a872SSerge Pavlov };
6406b7a872SSerge Pavlov C6a<long> c6a;
6506b7a872SSerge Pavlov C6b<int*> c6b; // expected-note{{in instantiation of template class 'C6b<int *>' requested here}}
6606b7a872SSerge Pavlov
6706b7a872SSerge Pavlov void func7(int);
6806b7a872SSerge Pavlov template<typename T> struct C7 {
func7(int)6906b7a872SSerge Pavlov friend void func7(int) {} // expected-error{{redefinition of 'func7'}}
7006b7a872SSerge Pavlov // expected-note@-1{{previous definition is here}}
7106b7a872SSerge Pavlov };
7206b7a872SSerge Pavlov C7<long> c7a;
7306b7a872SSerge Pavlov C7<int*> c7b; // expected-note{{in instantiation of template class 'C7<int *>' requested here}}
7406b7a872SSerge Pavlov
7506b7a872SSerge Pavlov
7606b7a872SSerge Pavlov // Even if clases are not instantiated and hence friend functions defined in them are not
7706b7a872SSerge Pavlov // available, their declarations can be checked.
7806b7a872SSerge Pavlov
7906b7a872SSerge Pavlov void func8(int); // expected-note{{previous declaration is here}}
8006b7a872SSerge Pavlov template<typename T> struct C8a {
8106b7a872SSerge Pavlov friend long func8(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
8206b7a872SSerge Pavlov };
8306b7a872SSerge Pavlov
8406b7a872SSerge Pavlov void func9(int); // expected-note{{previous declaration is here}}
8506b7a872SSerge Pavlov template<typename T> struct C9a {
8606b7a872SSerge Pavlov friend int func9(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
8706b7a872SSerge Pavlov };
8806b7a872SSerge Pavlov
8906b7a872SSerge Pavlov void func10(int); // expected-note{{previous declaration is here}}
9006b7a872SSerge Pavlov template<typename T> struct C10a {
9106b7a872SSerge Pavlov friend int func10(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
9206b7a872SSerge Pavlov };
9306b7a872SSerge Pavlov
9406b7a872SSerge Pavlov void func_11(); // expected-note{{previous declaration is here}}
9506b7a872SSerge Pavlov template<typename T> class C11 {
9606b7a872SSerge Pavlov friend int func_11(); // expected-error{{functions that differ only in their return type cannot be overloaded}}
9706b7a872SSerge Pavlov };
9806b7a872SSerge Pavlov
9906b7a872SSerge Pavlov void func_12(int x); // expected-note{{previous declaration is here}}
10006b7a872SSerge Pavlov template<typename T> class C12 {
10106b7a872SSerge Pavlov friend void func_12(int x = 0); // expected-error{{friend declaration specifying a default argument must be the only declaration}}
10206b7a872SSerge Pavlov };
10306b7a872SSerge Pavlov
104e6e534caSSerge Pavlov // Friend function with uninstantiated body is still a definition.
105e6e534caSSerge Pavlov
106e6e534caSSerge Pavlov template<typename T> struct C20 {
func_20()107e6e534caSSerge Pavlov friend void func_20() {} // expected-note{{previous definition is here}}
108e6e534caSSerge Pavlov };
109e6e534caSSerge Pavlov C20<int> c20i;
func_20()110e6e534caSSerge Pavlov void func_20() {} // expected-error{{redefinition of 'func_20'}}
111e6e534caSSerge Pavlov
112e6e534caSSerge Pavlov template<typename T> struct C21a {
func_21()113e6e534caSSerge Pavlov friend void func_21() {} // expected-note{{previous definition is here}}
114e6e534caSSerge Pavlov };
115e6e534caSSerge Pavlov template<typename T> struct C21b {
func_21()116e6e534caSSerge Pavlov friend void func_21() {} // expected-error{{redefinition of 'func_21'}}
117e6e534caSSerge Pavlov };
118e6e534caSSerge Pavlov C21a<int> c21ai;
119e6e534caSSerge Pavlov C21b<int> c21bi; // expected-note{{in instantiation of template class 'C21b<int>' requested here}}
120e6e534caSSerge Pavlov
121e6e534caSSerge Pavlov template<typename T> struct C22a {
func_22()122e6e534caSSerge Pavlov friend void func_22() {} // expected-note{{previous definition is here}}
123e6e534caSSerge Pavlov };
124e6e534caSSerge Pavlov template<typename T> struct C22b {
125e6e534caSSerge Pavlov friend void func_22();
126e6e534caSSerge Pavlov };
127e6e534caSSerge Pavlov C22a<int> c22ai;
128e6e534caSSerge Pavlov C22b<int> c22bi;
func_22()129e6e534caSSerge Pavlov void func_22() {} // expected-error{{redefinition of 'func_22'}}
130e6e534caSSerge Pavlov
131e6e534caSSerge Pavlov
132*acfcd78aSSerge Pavlov // Case of template friend functions.
133*acfcd78aSSerge Pavlov
134*acfcd78aSSerge Pavlov template<typename T> void func_31(T *x);
135*acfcd78aSSerge Pavlov template<typename T1>
136*acfcd78aSSerge Pavlov struct C31a {
func_31(T * x)137*acfcd78aSSerge Pavlov template<typename T> friend void func_31(T *x) {}
138*acfcd78aSSerge Pavlov };
139*acfcd78aSSerge Pavlov template<typename T1>
140*acfcd78aSSerge Pavlov struct C31b {
func_31(T * x)141*acfcd78aSSerge Pavlov template<typename T> friend void func_31(T *x) {}
142*acfcd78aSSerge Pavlov };
143*acfcd78aSSerge Pavlov
144*acfcd78aSSerge Pavlov
func_32(T * x)145*acfcd78aSSerge Pavlov template<typename T> inline void func_32(T *x) {}
146*acfcd78aSSerge Pavlov template<typename T1>
147*acfcd78aSSerge Pavlov struct C32a {
func_32(T * x)148*acfcd78aSSerge Pavlov template<typename T> friend void func_32(T *x) {}
149*acfcd78aSSerge Pavlov };
150*acfcd78aSSerge Pavlov template<typename T1>
151*acfcd78aSSerge Pavlov struct C32b {
func_32(T * x)152*acfcd78aSSerge Pavlov template<typename T> friend void func_32(T *x) {}
153*acfcd78aSSerge Pavlov };
154*acfcd78aSSerge Pavlov
155*acfcd78aSSerge Pavlov
156*acfcd78aSSerge Pavlov template<typename T1>
157*acfcd78aSSerge Pavlov struct C33a {
func_33(T * x)158*acfcd78aSSerge Pavlov template<typename T> friend void func_33(T *x) {}
159*acfcd78aSSerge Pavlov };
160*acfcd78aSSerge Pavlov template<typename T1>
161*acfcd78aSSerge Pavlov struct C33b {
func_33(T * x)162*acfcd78aSSerge Pavlov template<typename T> friend void func_33(T *x) {}
163*acfcd78aSSerge Pavlov };
164*acfcd78aSSerge Pavlov
165*acfcd78aSSerge Pavlov
func_34(T * x)166*acfcd78aSSerge Pavlov template<typename T> inline void func_34(T *x) {} // expected-note{{previous definition is here}}
167*acfcd78aSSerge Pavlov template<typename T1>
168*acfcd78aSSerge Pavlov struct C34 {
func_34(T * x)169*acfcd78aSSerge Pavlov template<typename T> friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}}
170*acfcd78aSSerge Pavlov };
171*acfcd78aSSerge Pavlov
172*acfcd78aSSerge Pavlov C34<int> v34; // expected-note{{in instantiation of template class 'C34<int>' requested here}}
173*acfcd78aSSerge Pavlov
174*acfcd78aSSerge Pavlov
175*acfcd78aSSerge Pavlov template<typename T> inline void func_35(T *x);
176*acfcd78aSSerge Pavlov template<typename T1>
177*acfcd78aSSerge Pavlov struct C35a {
func_35(T * x)178*acfcd78aSSerge Pavlov template<typename T> friend void func_35(T *x) {} // expected-note{{previous definition is here}}
179*acfcd78aSSerge Pavlov };
180*acfcd78aSSerge Pavlov template<typename T1>
181*acfcd78aSSerge Pavlov struct C35b {
func_35(T * x)182*acfcd78aSSerge Pavlov template<typename T> friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}}
183*acfcd78aSSerge Pavlov };
184*acfcd78aSSerge Pavlov
185*acfcd78aSSerge Pavlov C35a<int> v35a;
186*acfcd78aSSerge Pavlov C35b<int> v35b; // expected-note{{in instantiation of template class 'C35b<int>' requested here}}
187*acfcd78aSSerge Pavlov
188*acfcd78aSSerge Pavlov
189*acfcd78aSSerge Pavlov template<typename T> void func_36(T *x);
190*acfcd78aSSerge Pavlov template<typename T1>
191*acfcd78aSSerge Pavlov struct C36 {
func_36(T * x)192*acfcd78aSSerge Pavlov template<typename T> friend void func_36(T *x) {} // expected-error{{redefinition of 'func_36'}}
193*acfcd78aSSerge Pavlov // expected-note@-1{{previous definition is here}}
194*acfcd78aSSerge Pavlov };
195*acfcd78aSSerge Pavlov
196*acfcd78aSSerge Pavlov C36<int> v36a;
197*acfcd78aSSerge Pavlov C36<long> v36b; //expected-note{{in instantiation of template class 'C36<long>' requested here}}
198*acfcd78aSSerge Pavlov
199*acfcd78aSSerge Pavlov
200*acfcd78aSSerge Pavlov template<typename T> void func_37(T *x);
201*acfcd78aSSerge Pavlov template<typename T1>
202*acfcd78aSSerge Pavlov struct C37 {
func_37(T * x)203*acfcd78aSSerge Pavlov template<typename T> friend void func_37(T *x) {} // expected-note{{previous definition is here}}
204*acfcd78aSSerge Pavlov };
205*acfcd78aSSerge Pavlov
206*acfcd78aSSerge Pavlov C37<int> v37;
func_37(T * x)207*acfcd78aSSerge Pavlov template<typename T> void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}}
208*acfcd78aSSerge Pavlov
20906b7a872SSerge Pavlov
21006b7a872SSerge Pavlov namespace pr22307 {
21106b7a872SSerge Pavlov
21206b7a872SSerge Pavlov struct t {
21306b7a872SSerge Pavlov friend int leak(t);
21406b7a872SSerge Pavlov };
21506b7a872SSerge Pavlov
21606b7a872SSerge Pavlov template<typename v>
21706b7a872SSerge Pavlov struct m {
leak(t)21806b7a872SSerge Pavlov friend int leak(t) { return sizeof(v); } // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}}
21906b7a872SSerge Pavlov };
22006b7a872SSerge Pavlov
22106b7a872SSerge Pavlov template struct m<char>;
22206b7a872SSerge Pavlov template struct m<short>; // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}}
22306b7a872SSerge Pavlov
main()22406b7a872SSerge Pavlov int main() {
22506b7a872SSerge Pavlov leak(t());
22606b7a872SSerge Pavlov }
22706b7a872SSerge Pavlov
22806b7a872SSerge Pavlov }
22906b7a872SSerge Pavlov
23006b7a872SSerge Pavlov namespace pr17923 {
23106b7a872SSerge Pavlov
23206b7a872SSerge Pavlov void f(unsigned long long);
23306b7a872SSerge Pavlov
23406b7a872SSerge Pavlov template<typename T> struct X {
f(unsigned long long)23506b7a872SSerge Pavlov friend void f(unsigned long long) {
23606b7a872SSerge Pavlov T t;
23706b7a872SSerge Pavlov }
23806b7a872SSerge Pavlov };
23906b7a872SSerge Pavlov
main()24006b7a872SSerge Pavlov int main() { f(1234); }
24106b7a872SSerge Pavlov
24206b7a872SSerge Pavlov }
24306b7a872SSerge Pavlov
24406b7a872SSerge Pavlov namespace pr17923a {
24506b7a872SSerge Pavlov
24606b7a872SSerge Pavlov int get();
24706b7a872SSerge Pavlov
24806b7a872SSerge Pavlov template< int value >
24906b7a872SSerge Pavlov class set {
get()25006b7a872SSerge Pavlov friend int get()
25106b7a872SSerge Pavlov { return value; } // return 0; is OK
25206b7a872SSerge Pavlov };
25306b7a872SSerge Pavlov
25406b7a872SSerge Pavlov template class set< 5 >;
25506b7a872SSerge Pavlov
main()25606b7a872SSerge Pavlov int main() {
25706b7a872SSerge Pavlov get();
25806b7a872SSerge Pavlov }
25906b7a872SSerge Pavlov
26006b7a872SSerge Pavlov }
26106b7a872SSerge Pavlov
26206b7a872SSerge Pavlov namespace pr8035 {
26306b7a872SSerge Pavlov
26406b7a872SSerge Pavlov void Function();
26506b7a872SSerge Pavlov
main(int argc,char * argv[])26606b7a872SSerge Pavlov int main(int argc, char* argv[]) {
26706b7a872SSerge Pavlov Function();
26806b7a872SSerge Pavlov }
26906b7a872SSerge Pavlov
27006b7a872SSerge Pavlov template <typename T>
27106b7a872SSerge Pavlov struct Test {
Function()27206b7a872SSerge Pavlov friend void Function() { }
27306b7a872SSerge Pavlov };
27406b7a872SSerge Pavlov
27506b7a872SSerge Pavlov template class Test<int>;
27606b7a872SSerge Pavlov
27706b7a872SSerge Pavlov }
27825dbe1a1SSerge Pavlov
27925dbe1a1SSerge Pavlov namespace pr14785 {
28025dbe1a1SSerge Pavlov template<typename T>
28125dbe1a1SSerge Pavlov struct Somewhat {
internalpr14785::Somewhat28225dbe1a1SSerge Pavlov void internal() const { }
operator +(int const &,Somewhat<T> const &)28325dbe1a1SSerge Pavlov friend void operator+(int const &, Somewhat<T> const &) {} // expected-error{{redefinition of 'operator+'}}
28425dbe1a1SSerge Pavlov };
28525dbe1a1SSerge Pavlov
operator +(int const &,Somewhat<char> const & x)28625dbe1a1SSerge Pavlov void operator+(int const &, Somewhat<char> const &x) { // expected-note {{previous definition is here}}
28725dbe1a1SSerge Pavlov x.internal(); // expected-note{{in instantiation of template class 'pr14785::Somewhat<char>' requested here}}
28825dbe1a1SSerge Pavlov }
28925dbe1a1SSerge Pavlov }
29025dbe1a1SSerge Pavlov
29125dbe1a1SSerge Pavlov namespace D30375 {
29225dbe1a1SSerge Pavlov template <typename K> struct B {
29325dbe1a1SSerge Pavlov template <typename A> bool insert(A &);
29425dbe1a1SSerge Pavlov };
29525dbe1a1SSerge Pavlov
29625dbe1a1SSerge Pavlov template <typename K>
insert(A & x)29725dbe1a1SSerge Pavlov template <typename A> bool B<K>::insert(A &x) { return x < x; }
29825dbe1a1SSerge Pavlov
29925dbe1a1SSerge Pavlov template <typename K> class D {
30025dbe1a1SSerge Pavlov B<K> t;
30125dbe1a1SSerge Pavlov
30225dbe1a1SSerge Pavlov public:
30325dbe1a1SSerge Pavlov K x;
insert()30425dbe1a1SSerge Pavlov bool insert() { return t.insert(x); }
30525dbe1a1SSerge Pavlov template <typename K1> friend bool operator<(const D<K1> &, const D<K1> &);
30625dbe1a1SSerge Pavlov };
30725dbe1a1SSerge Pavlov
30825dbe1a1SSerge Pavlov template <typename K> bool operator<(const D<K> &, const D<K> &);
30925dbe1a1SSerge Pavlov
func()31025dbe1a1SSerge Pavlov void func() {
31125dbe1a1SSerge Pavlov D<D<int>> cache;
31225dbe1a1SSerge Pavlov cache.insert();
31325dbe1a1SSerge Pavlov }
31425dbe1a1SSerge Pavlov }
315*acfcd78aSSerge Pavlov
316*acfcd78aSSerge Pavlov namespace PR39742 {
317*acfcd78aSSerge Pavlov template<typename>
318*acfcd78aSSerge Pavlov struct wrapper {
319*acfcd78aSSerge Pavlov template<typename>
friend_function_template()320*acfcd78aSSerge Pavlov friend void friend_function_template() {} // expected-error{{redefinition of 'friend_function_template'}}
321*acfcd78aSSerge Pavlov // expected-note@-1{{previous definition is here}}
322*acfcd78aSSerge Pavlov };
323*acfcd78aSSerge Pavlov
324*acfcd78aSSerge Pavlov wrapper<bool> x;
325*acfcd78aSSerge Pavlov wrapper<int> y; // expected-note{{in instantiation of template class 'PR39742::wrapper<int>' requested here}}
326*acfcd78aSSerge Pavlov }
327