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