1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 // PR5057 3 namespace test0 { 4 namespace std { 5 class X { 6 public: 7 template<typename T> friend struct Y; 8 }; 9 } 10 11 namespace std { 12 template<typename T> struct Y {}; 13 } 14 } 15 16 namespace test1 { f1(T)17 template<typename T> void f1(T) { } // expected-note{{here}} 18 19 class X { 20 template<typename T> friend void f0(T); 21 template<typename T> friend void f1(T); 22 }; 23 f0(T)24 template<typename T> void f0(T) { } f1(T)25 template<typename T> void f1(T) { } // expected-error{{redefinition}} 26 } 27 28 // PR4768 29 namespace test2 { 30 template<typename T> struct X0 { 31 template<typename U> friend struct X0; 32 }; 33 34 template<typename T> struct X0<T*> { 35 template<typename U> friend struct X0; 36 }; 37 38 template<> struct X0<int> { 39 template<typename U> friend struct X0; 40 }; 41 42 template<typename T> struct X1 { 43 template<typename U> friend void f2(U); 44 template<typename U> friend void f3(U); 45 }; 46 47 template<typename U> void f2(U); 48 49 X1<int> x1i; 50 X0<int*> x0ip; 51 52 template<> void f2(int); 53 54 // FIXME: Should this declaration of f3 be required for the specialization of 55 // f3<int> (further below) to work? GCC and EDG don't require it, we do... 56 template<typename U> void f3(U); 57 58 template<> void f3(int); 59 } 60 61 // PR5332 62 namespace test3 { 63 template <typename T> class Foo { 64 template <typename U> 65 friend class Foo; 66 }; 67 68 Foo<int> foo; 69 70 template<typename T, T Value> struct X2a; 71 72 template<typename T, int Size> struct X2b; 73 74 template<typename T> 75 class X3 { 76 template<typename U, U Value> friend struct X2a; 77 78 // FIXME: the redeclaration note ends up here because redeclaration 79 // lookup ends up finding the friend target from X3<int>. 80 template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \ 81 // expected-note {{previous non-type template parameter with type 'int' is here}} 82 }; 83 84 X3<int> x3i; // okay 85 86 X3<long> x3l; // expected-note {{in instantiation}} 87 } 88 89 // PR5716 90 namespace test4 { 91 template<typename> struct A { 92 template<typename T> friend void f(const A<T>&); 93 }; 94 f(const A<T> &)95 template<typename T> void f(const A<T>&) { 96 int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} 97 } 98 f()99 void f() { 100 f(A<int>()); // expected-note {{in instantiation of function template specialization}} 101 } 102 } 103 104 namespace test5 { 105 class outer { 106 class foo; 107 template <typename T> friend struct cache; 108 }; 109 class outer::foo { 110 template <typename T> friend struct cache; 111 }; 112 } 113 114 // PR6022 115 namespace PR6022 { 116 template <class T1, class T2 , class T3 > class A; 117 118 namespace inner { 119 template<class T1, class T2, class T3, class T> 120 A<T1, T2, T3>& f0(A<T1, T2, T3>&, T); 121 } 122 123 template<class T1, class T2, class T3> 124 class A { 125 template<class U1, class U2, class U3, class T> 126 friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T); 127 }; 128 } 129 130 namespace FriendTemplateDefinition { 131 template<unsigned > struct int_c { }; 132 133 template<typename T> 134 struct X { 135 template<unsigned N> f(X,int_c<N>)136 friend void f(X, int_c<N>) { 137 int value = N; 138 }; 139 }; 140 test_X(X<int> x,int_c<5> i5)141 void test_X(X<int> x, int_c<5> i5) { 142 f(x, i5); 143 } 144 } 145 146 namespace PR7013a { 147 template<class > struct X0 148 { 149 typedef int type; 150 }; 151 template<typename > struct X1 152 { 153 }; 154 template<typename , typename T> struct X2 155 { 156 typename T::type e; 157 }; 158 namespace N 159 { 160 template <typename = int, typename = X1<int> > struct X3 161 { 162 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); 163 }; op(X2<Ch,Tr> &,B)164 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) 165 { 166 X2<int, Tr> s; 167 } 168 } n()169 int n() 170 { 171 X2<int, X0<int> > ngs; 172 N::X3<> b; 173 op(ngs, b); 174 return 0; 175 } 176 } 177 178 namespace PR7013b { 179 template<class > struct X0 180 { 181 typedef int type; 182 }; 183 template<typename > struct X1 184 { 185 }; 186 template<typename , typename T> struct X2 187 { 188 typename T::type e; 189 }; 190 namespace N 191 { 192 template <typename = X1<int> > struct X3 193 { 194 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); 195 }; op(X2<Ch,Tr> &,B)196 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) 197 { 198 X2<int, Tr> s; 199 } 200 } n()201 int n() 202 { 203 X2<int, X0<int> > ngs; 204 N::X3<> b; 205 op(ngs, b); 206 return 0; 207 } 208 209 } 210 211 namespace PR8649 { 212 template<typename T, typename U, unsigned N> 213 struct X { 214 template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}} 215 }; 216 217 X<int, float, 7> x; 218 } 219 220 // Don't crash, and error on invalid friend type template. 221 namespace friend_type_template_no_tag { 222 template <typename T> struct S { 223 template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}} 224 }; 225 template struct S<int>; 226 } 227 228 namespace PR10660 { 229 struct A { 230 template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} 231 }; 232 } 233 234 namespace rdar11147355 { 235 template <class T> 236 struct A { 237 template <class U> class B; 238 template <class S> template <class U> friend class A<S>::B; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}} 239 private: 240 int n; // expected-note {{here}} 241 }; 242 243 template <class S> template <class U> class A<S>::B { 244 public: 245 // FIXME: This should be permitted. f(A<S * > a)246 int f(A<S*> a) { return a.n; } // expected-error {{private}} 247 }; 248 249 A<double>::B<double> ab; 250 A<double*> a; 251 int k = ab.f(a); // expected-note {{instantiation of}} 252 } 253 254 namespace RedeclUnrelated { 255 struct S { 256 int packaged_task; 257 template<typename> class future { 258 template<typename> friend class packaged_task; 259 }; 260 future<void> share; 261 }; 262 } 263 264 namespace PR12557 { 265 template <typename> 266 struct Foo; 267 268 template <typename Foo_> 269 struct Bar { 270 typedef Foo_ Foo; // expected-note {{previous}} 271 272 template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}} 273 }; 274 275 Bar<int> b; 276 } 277 278 namespace PR12585 { 279 struct A { }; 280 template<typename> struct B { 281 template<typename> friend class A::does_not_exist; // \ 282 // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}} 283 }; 284 285 struct C { 286 template<typename> struct D; 287 }; 288 template<typename> class E { 289 int n; 290 template<typename> friend struct C::D; 291 }; 292 template<typename T> struct C::D { fPR12585::C::D293 int f() { 294 return E<int>().n; 295 } 296 }; 297 int n = C::D<void*>().f(); 298 299 struct F { 300 template<int> struct G; 301 }; 302 template<typename T> struct H { 303 // FIXME: As with cases above, the note here is on an unhelpful declaration, 304 // and should point to the declaration of G within F. 305 template<T> friend struct F::G; // \ 306 // expected-error {{different type 'char' in template redeclaration}} \ 307 // expected-note {{previous}} 308 }; 309 H<int> h1; // ok 310 H<char> h2; // expected-note {{instantiation}} 311 } 312 313 // Ensure that we can still instantiate a friend function template 314 // after the friend declaration is instantiated during the delayed 315 // parsing of a member function, but before the friend function has 316 // been parsed. 317 namespace rdar12350696 { 318 template <class T> struct A { foordar12350696::A319 void foo() { 320 A<int> a; 321 } foo(const A<U> & a)322 template <class U> friend void foo(const A<U> & a) { 323 int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}} 324 } 325 }; 326 test()327 void test() { 328 A<int> b; 329 foo(b); // expected-note {{in instantiation}} 330 } 331 } 332