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