|  | // 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<typename T> struct C2b { | 
|  | friend void func2(int) {} | 
|  | }; | 
|  |  | 
|  | void func3(int); | 
|  | struct C3a { | 
|  | friend void func3(int) {}  // expected-note{{previous definition is here}} | 
|  | }; | 
|  | template<typename T> struct C3b { | 
|  | friend void func3(int) {}  // expected-error{{redefinition of 'func3'}} | 
|  | }; | 
|  | C3b<long> c3;  // expected-note{{in instantiation of template class 'C3b<long>' 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<typename T> struct C4a { | 
|  | friend void func4(int) {} | 
|  | }; | 
|  | template<typename T> struct C4b { | 
|  | friend void func4(int) {} | 
|  | }; | 
|  |  | 
|  |  | 
|  | void func5(int); | 
|  | template<typename T> struct C5a { | 
|  | friend void func5(int) {} | 
|  | }; | 
|  | template<typename T> struct C5b { | 
|  | friend void func5(int) {} | 
|  | }; | 
|  | C5a<long> c5a; | 
|  |  | 
|  | void func6(int); | 
|  | template<typename T> struct C6a { | 
|  | friend void func6(int) {}  // expected-note{{previous definition is here}} | 
|  | }; | 
|  | template<typename T> struct C6b { | 
|  | friend void func6(int) {}  // expected-error{{redefinition of 'func6'}} | 
|  | }; | 
|  | C6a<long> c6a; | 
|  | C6b<int*> c6b;  // expected-note{{in instantiation of template class 'C6b<int *>' requested here}} | 
|  |  | 
|  | void func7(int); | 
|  | template<typename T> struct C7 { | 
|  | friend void func7(int) {}  // expected-error{{redefinition of 'func7'}} | 
|  | // expected-note@-1{{previous definition is here}} | 
|  | }; | 
|  | C7<long> c7a; | 
|  | C7<int*> c7b;  // expected-note{{in instantiation of template class 'C7<int *>' 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<typename T> 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<typename T> 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<typename T> 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<typename T> 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<typename T> 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<typename T> struct C20 { | 
|  | friend void func_20() {} // expected-note{{previous definition is here}} | 
|  | }; | 
|  | C20<int> c20i; | 
|  | void func_20() {} // expected-error{{redefinition of 'func_20'}} | 
|  |  | 
|  | template<typename T> struct C21a { | 
|  | friend void func_21() {} // expected-note{{previous definition is here}} | 
|  | }; | 
|  | template<typename T> struct C21b { | 
|  | friend void func_21() {} // expected-error{{redefinition of 'func_21'}} | 
|  | }; | 
|  | C21a<int> c21ai; | 
|  | C21b<int> c21bi; // expected-note{{in instantiation of template class 'C21b<int>' requested here}} | 
|  |  | 
|  | template<typename T> struct C22a { | 
|  | friend void func_22() {} // expected-note{{previous definition is here}} | 
|  | }; | 
|  | template<typename T> struct C22b { | 
|  | friend void func_22(); | 
|  | }; | 
|  | C22a<int> c22ai; | 
|  | C22b<int> c22bi; | 
|  | void func_22() {} // expected-error{{redefinition of 'func_22'}} | 
|  |  | 
|  |  | 
|  | // Case of template friend functions. | 
|  |  | 
|  | template<typename T> void func_31(T *x); | 
|  | template<typename T1> | 
|  | struct C31a { | 
|  | template<typename T> friend void func_31(T *x) {} | 
|  | }; | 
|  | template<typename T1> | 
|  | struct C31b { | 
|  | template<typename T> friend void func_31(T *x) {} | 
|  | }; | 
|  |  | 
|  |  | 
|  | template<typename T> inline void func_32(T *x) {} | 
|  | template<typename T1> | 
|  | struct C32a { | 
|  | template<typename T> friend void func_32(T *x) {} | 
|  | }; | 
|  | template<typename T1> | 
|  | struct C32b { | 
|  | template<typename T> friend void func_32(T *x) {} | 
|  | }; | 
|  |  | 
|  |  | 
|  | template<typename T1> | 
|  | struct C33a { | 
|  | template<typename T> friend void func_33(T *x) {} | 
|  | }; | 
|  | template<typename T1> | 
|  | struct C33b { | 
|  | template<typename T> friend void func_33(T *x) {} | 
|  | }; | 
|  |  | 
|  |  | 
|  | template<typename T> inline void func_34(T *x) {}  // expected-note{{previous definition is here}} | 
|  | template<typename T1> | 
|  | struct C34 { | 
|  | template<typename T> friend void func_34(T *x) {} // expected-error{{redefinition of 'func_34'}} | 
|  | }; | 
|  |  | 
|  | C34<int> v34;  // expected-note{{in instantiation of template class 'C34<int>' requested here}} | 
|  |  | 
|  |  | 
|  | template<typename T> inline void func_35(T *x); | 
|  | template<typename T1> | 
|  | struct C35a { | 
|  | template<typename T> friend void func_35(T *x) {} // expected-note{{previous definition is here}} | 
|  | }; | 
|  | template<typename T1> | 
|  | struct C35b { | 
|  | template<typename T> friend void func_35(T *x) {} // expected-error{{redefinition of 'func_35'}} | 
|  | }; | 
|  |  | 
|  | C35a<int> v35a; | 
|  | C35b<int> v35b;  // expected-note{{in instantiation of template class 'C35b<int>' requested here}} | 
|  |  | 
|  |  | 
|  | template<typename T> void func_36(T *x); | 
|  | template<typename T1> | 
|  | struct C36 { | 
|  | template<typename T> friend void func_36(T *x) {}  // expected-error{{redefinition of 'func_36'}} | 
|  | // expected-note@-1{{previous definition is here}} | 
|  | }; | 
|  |  | 
|  | C36<int> v36a; | 
|  | C36<long> v36b;  //expected-note{{in instantiation of template class 'C36<long>' requested here}} | 
|  |  | 
|  |  | 
|  | template<typename T> void func_37(T *x); | 
|  | template<typename T1> | 
|  | struct C37 { | 
|  | template<typename T> friend void func_37(T *x) {} // expected-note{{previous definition is here}} | 
|  | }; | 
|  |  | 
|  | C37<int> v37; | 
|  | template<typename T> void func_37(T *x) {} // expected-error{{redefinition of 'func_37'}} | 
|  |  | 
|  |  | 
|  | namespace pr22307 { | 
|  |  | 
|  | struct t { | 
|  | friend int leak(t); | 
|  | }; | 
|  |  | 
|  | template<typename v> | 
|  | struct m { | 
|  | friend int leak(t) { return sizeof(v); }  // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}} | 
|  | }; | 
|  |  | 
|  | template struct m<char>; | 
|  | template struct m<short>;  // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}} | 
|  |  | 
|  | int main() { | 
|  | leak(t()); | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace pr17923 { | 
|  |  | 
|  | void f(unsigned long long); | 
|  |  | 
|  | template<typename T> 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 <typename T> | 
|  | struct Test { | 
|  | friend void Function() { } | 
|  | }; | 
|  |  | 
|  | template class Test<int>; | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace pr14785 { | 
|  | template<typename T> | 
|  | struct Somewhat { | 
|  | void internal() const { } | 
|  | friend void operator+(int const &, Somewhat<T> const &) {}  // expected-error{{redefinition of 'operator+'}} | 
|  | }; | 
|  |  | 
|  | void operator+(int const &, Somewhat<char> const &x) {  // expected-note {{previous definition is here}} | 
|  | x.internal();  // expected-note{{in instantiation of template class 'pr14785::Somewhat<char>' requested here}} | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace D30375 { | 
|  | template <typename K> struct B { | 
|  | template <typename A> bool insert(A &); | 
|  | }; | 
|  |  | 
|  | template <typename K> | 
|  | template <typename A> bool B<K>::insert(A &x) { return x < x; } | 
|  |  | 
|  | template <typename K> class D { | 
|  | B<K> t; | 
|  |  | 
|  | public: | 
|  | K x; | 
|  | bool insert() { return t.insert(x); } | 
|  | template <typename K1> friend bool operator<(const D<K1> &, const D<K1> &); | 
|  | }; | 
|  |  | 
|  | template <typename K> bool operator<(const D<K> &, const D<K> &); | 
|  |  | 
|  | void func() { | 
|  | D<D<int>> cache; | 
|  | cache.insert(); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR39742 { | 
|  | template<typename> | 
|  | struct wrapper { | 
|  | template<typename> | 
|  | friend void friend_function_template() {}  // expected-error{{redefinition of 'friend_function_template'}} | 
|  | // expected-note@-1{{previous definition is here}} | 
|  | }; | 
|  |  | 
|  | wrapper<bool> x; | 
|  | wrapper<int> y;  // expected-note{{in instantiation of template class 'PR39742::wrapper<int>' requested here}} | 
|  | } |