1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li 3*67e74705SXin Li // C++98 [class.friend]p7: 4*67e74705SXin Li // C++11 [class.friend]p9: 5*67e74705SXin Li // A name nominated by a friend declaration shall be accessible in 6*67e74705SXin Li // the scope of the class containing the friend declaration. 7*67e74705SXin Li 8*67e74705SXin Li // PR12328 9*67e74705SXin Li // Simple, non-templated case. 10*67e74705SXin Li namespace test0 { 11*67e74705SXin Li class X { 12*67e74705SXin Li void f(); // expected-note {{implicitly declared private here}} 13*67e74705SXin Li }; 14*67e74705SXin Li 15*67e74705SXin Li class Y { 16*67e74705SXin Li friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test0::X'}} 17*67e74705SXin Li }; 18*67e74705SXin Li } 19*67e74705SXin Li 20*67e74705SXin Li // Templated but non-dependent. 21*67e74705SXin Li namespace test1 { 22*67e74705SXin Li class X { 23*67e74705SXin Li void f(); // expected-note {{implicitly declared private here}} 24*67e74705SXin Li }; 25*67e74705SXin Li 26*67e74705SXin Li template <class T> class Y { 27*67e74705SXin Li friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test1::X'}} 28*67e74705SXin Li }; 29*67e74705SXin Li } 30*67e74705SXin Li 31*67e74705SXin Li // Dependent but instantiated at the right type. 32*67e74705SXin Li namespace test2 { 33*67e74705SXin Li template <class T> class Y; 34*67e74705SXin Li 35*67e74705SXin Li class X { 36*67e74705SXin Li void f(); 37*67e74705SXin Li friend class Y<int>; 38*67e74705SXin Li }; 39*67e74705SXin Li 40*67e74705SXin Li template <class T> class Y { 41*67e74705SXin Li friend void X::f(); 42*67e74705SXin Li }; 43*67e74705SXin Li 44*67e74705SXin Li template class Y<int>; 45*67e74705SXin Li } 46*67e74705SXin Li 47*67e74705SXin Li // Dependent and instantiated at the wrong type. 48*67e74705SXin Li namespace test3 { 49*67e74705SXin Li template <class T> class Y; 50*67e74705SXin Li 51*67e74705SXin Li class X { 52*67e74705SXin Li void f(); // expected-note {{implicitly declared private here}} 53*67e74705SXin Li friend class Y<int>; 54*67e74705SXin Li }; 55*67e74705SXin Li 56*67e74705SXin Li template <class T> class Y { 57*67e74705SXin Li friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test3::X'}} 58*67e74705SXin Li }; 59*67e74705SXin Li 60*67e74705SXin Li template class Y<float>; // expected-note {{in instantiation}} 61*67e74705SXin Li } 62*67e74705SXin Li 63*67e74705SXin Li // Dependent because dependently-scoped. 64*67e74705SXin Li namespace test4 { 65*67e74705SXin Li template <class T> class X { 66*67e74705SXin Li void f(); 67*67e74705SXin Li }; 68*67e74705SXin Li 69*67e74705SXin Li template <class T> class Y { 70*67e74705SXin Li friend void X<T>::f(); 71*67e74705SXin Li }; 72*67e74705SXin Li } 73*67e74705SXin Li 74*67e74705SXin Li // Dependently-scoped, no friends. 75*67e74705SXin Li namespace test5 { 76*67e74705SXin Li template <class T> class X { 77*67e74705SXin Li void f(); // expected-note {{implicitly declared private here}} 78*67e74705SXin Li }; 79*67e74705SXin Li 80*67e74705SXin Li template <class T> class Y { 81*67e74705SXin Li friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test5::X<int>'}} 82*67e74705SXin Li }; 83*67e74705SXin Li 84*67e74705SXin Li template class Y<int>; // expected-note {{in instantiation}} 85*67e74705SXin Li } 86*67e74705SXin Li 87*67e74705SXin Li // Dependently-scoped, wrong friend. 88*67e74705SXin Li namespace test6 { 89*67e74705SXin Li template <class T> class Y; 90*67e74705SXin Li 91*67e74705SXin Li template <class T> class X { 92*67e74705SXin Li void f(); // expected-note {{implicitly declared private here}} 93*67e74705SXin Li friend class Y<float>; 94*67e74705SXin Li }; 95*67e74705SXin Li 96*67e74705SXin Li template <class T> class Y { 97*67e74705SXin Li friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test6::X<int>'}} 98*67e74705SXin Li }; 99*67e74705SXin Li 100*67e74705SXin Li template class Y<int>; // expected-note {{in instantiation}} 101*67e74705SXin Li } 102*67e74705SXin Li 103*67e74705SXin Li // Dependently-scoped, right friend. 104*67e74705SXin Li namespace test7 { 105*67e74705SXin Li template <class T> class Y; 106*67e74705SXin Li 107*67e74705SXin Li template <class T> class X { 108*67e74705SXin Li void f(); 109*67e74705SXin Li friend class Y<int>; 110*67e74705SXin Li }; 111*67e74705SXin Li 112*67e74705SXin Li template <class T> class Y { 113*67e74705SXin Li friend void X<T>::f(); 114*67e74705SXin Li }; 115*67e74705SXin Li 116*67e74705SXin Li template class Y<int>; 117*67e74705SXin Li } 118