// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 // If a friend function is defined in several non-template classes, // it is an error. void func1(int); struct C1a { friend void func1(int) {} // expected-note{{previous definition is here}} }; struct C1b { friend void func1(int) {} // expected-error{{redefinition of 'func1'}} }; // If a friend function is defined in both non-template and template // classes it is an error only if the template is instantiated. void func2(int); struct C2a { friend void func2(int) {} }; template struct C2b { friend void func2(int) {} }; void func3(int); struct C3a { friend void func3(int) {} // expected-note{{previous definition is here}} }; template struct C3b { friend void func3(int) {} // expected-error{{redefinition of 'func3'}} }; C3b c3; // expected-note{{in instantiation of template class 'C3b' requested here}} // If a friend function is defined in several template classes it is an error // only if several templates are instantiated. void func4(int); template struct C4a { friend void func4(int) {} }; template struct C4b { friend void func4(int) {} }; void func5(int); template struct C5a { friend void func5(int) {} }; template struct C5b { friend void func5(int) {} }; C5a c5a; void func6(int); template struct C6a { friend void func6(int) {} // expected-note{{previous definition is here}} }; template struct C6b { friend void func6(int) {} // expected-error{{redefinition of 'func6'}} }; C6a c6a; C6b c6b; // expected-note{{in instantiation of template class 'C6b' requested here}} void func7(int); template struct C7 { friend void func7(int) {} // expected-error{{redefinition of 'func7'}} // expected-note@-1{{previous definition is here}} }; C7 c7a; C7 c7b; // expected-note{{in instantiation of template class 'C7' requested here}} // Even if clases are not instantiated and hence friend functions defined in them are not // available, their declarations can be checked. void func8(int); // expected-note{{previous declaration is here}} template struct C8a { friend long func8(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} }; void func9(int); // expected-note{{previous declaration is here}} template struct C9a { friend int func9(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} }; void func10(int); // expected-note{{previous declaration is here}} template struct C10a { friend int func10(int); // expected-error{{functions that differ only in their return type cannot be overloaded}} }; void func_11(); // expected-note{{previous declaration is here}} template class C11 { friend int func_11(); // expected-error{{functions that differ only in their return type cannot be overloaded}} }; void func_12(int x); // expected-note{{previous declaration is here}} template class C12 { friend void func_12(int x = 0); // expected-error{{friend declaration specifying a default argument must be the only declaration}} }; // Friend function with uninstantiated body is still a definition. template struct C20 { friend void func_20() {} // expected-note{{previous definition is here}} }; C20 c20i; void func_20() {} // expected-error{{redefinition of 'func_20'}} template struct C21a { friend void func_21() {} // expected-note{{previous definition is here}} }; template struct C21b { friend void func_21() {} // expected-error{{redefinition of 'func_21'}} }; C21a c21ai; C21b c21bi; // expected-note{{in instantiation of template class 'C21b' requested here}} template struct C22a { friend void func_22() {} // expected-note{{previous definition is here}} }; template struct C22b { friend void func_22(); }; C22a c22ai; C22b c22bi; void func_22() {} // expected-error{{redefinition of 'func_22'}} // Case of template friend functions. template void func_31(T *x); template struct C31a { template friend void func_31(T *x) {} }; template struct C31b { template friend void func_31(T *x) {} }; template inline void func_32(T *x) {} template struct C32a { template friend void func_32(T *x) {} }; template struct C32b { template friend void func_32(T *x) {} }; template struct C33a { template friend void func_33(T *x) {} }; template struct C33b { template friend void func_33(T *x) {} }; template inline void func_34(T *x) {} // expected-note{{previous definition is here}} template struct C34 { template friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}} }; C34 v34; // expected-note{{in instantiation of template class 'C34' requested here}} template inline void func_35(T *x); template struct C35a { template friend void func_35(T *x) {} // expected-note{{previous definition is here}} }; template struct C35b { template friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}} }; C35a v35a; C35b v35b; // expected-note{{in instantiation of template class 'C35b' requested here}} template void func_36(T *x); template struct C36 { template friend void func_36(T *x) {} // expected-error{{redefinition of 'func_36'}} // expected-note@-1{{previous definition is here}} }; C36 v36a; C36 v36b; //expected-note{{in instantiation of template class 'C36' requested here}} template void func_37(T *x); template struct C37 { template friend void func_37(T *x) {} // expected-note{{previous definition is here}} }; C37 v37; template void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}} namespace pr22307 { struct t { friend int leak(t); }; template struct m { friend int leak(t) { return sizeof(v); } // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}} }; template struct m; template struct m; // expected-note{{in instantiation of template class 'pr22307::m' requested here}} int main() { leak(t()); } } namespace pr17923 { void f(unsigned long long); template struct X { friend void f(unsigned long long) { T t; } }; int main() { f(1234); } } namespace pr17923a { int get(); template< int value > class set { friend int get() { return value; } // return 0; is OK }; template class set< 5 >; int main() { get(); } } namespace pr8035 { void Function(); int main(int argc, char* argv[]) { Function(); } template struct Test { friend void Function() { } }; template class Test; } namespace pr14785 { template struct Somewhat { void internal() const { } friend void operator+(int const &, Somewhat const &) {} // expected-error{{redefinition of 'operator+'}} }; void operator+(int const &, Somewhat const &x) { // expected-note {{previous definition is here}} x.internal(); // expected-note{{in instantiation of template class 'pr14785::Somewhat' requested here}} } } namespace D30375 { template struct B { template bool insert(A &); }; template template bool B::insert(A &x) { return x < x; } template class D { B t; public: K x; bool insert() { return t.insert(x); } template friend bool operator<(const D &, const D &); }; template bool operator<(const D &, const D &); void func() { D> cache; cache.insert(); } } namespace PR39742 { template struct wrapper { template friend void friend_function_template() {} // expected-error{{redefinition of 'friend_function_template'}} // expected-note@-1{{previous definition is here}} }; wrapper x; wrapper y; // expected-note{{in instantiation of template class 'PR39742::wrapper' requested here}} }