341 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// PR50573namespace 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 16namespace test1 {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 24 template<typename T> void f0(T) { }25 template<typename T> void f1(T) { } // expected-error{{redefinition}}26}27 28// PR476829namespace 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 of55 // 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// PR533262namespace 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 redeclaration79 // 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; // okay85 86 X3<long> x3l; // expected-note {{in instantiation}}87}88 89// PR571690namespace test4 {91 template<typename> struct A {92 template<typename T> friend void f(const A<T>&);93 };94 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 99 void f() {100 f(A<int>()); // expected-note {{in instantiation of function template specialization}}101 }102}103 104namespace 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// PR6022115namespace 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 130namespace FriendTemplateDefinition {131 template<unsigned > struct int_c { };132 133 template<typename T>134 struct X {135 template<unsigned N>136 friend void f(X, int_c<N>) {137 int value = N;138 };139 };140 141 void test_X(X<int> x, int_c<5> i5) {142 f(x, i5);143 }144}145 146namespace PR7013a {147 template<class > struct X0148 {149 typedef int type;150 };151 template<typename > struct X1152 {153 };154 template<typename , typename T> struct X2155 {156 typename T::type e;157 };158 namespace N159 {160 template <typename = int, typename = X1<int> > struct X3161 {162 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);163 };164 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)165 {166 X2<int, Tr> s;167 }168 }169 int n()170 {171 X2<int, X0<int> > ngs;172 N::X3<> b;173 op(ngs, b);174 return 0;175 }176}177 178namespace PR7013b {179 template<class > struct X0180 {181 typedef int type;182 };183 template<typename > struct X1184 {185 };186 template<typename , typename T> struct X2187 {188 typename T::type e;189 };190 namespace N191 {192 template <typename = X1<int> > struct X3193 {194 template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);195 };196 template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)197 {198 X2<int, Tr> s;199 }200 }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 211namespace 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.221namespace 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 228namespace PR10660 {229 struct A {230 template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}231 };232}233 234namespace 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.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 254namespace 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 264namespace 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 278namespace 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 {293 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; // ok310 H<char> h2; // expected-note {{instantiation}}311}312 313// Ensure that we can still instantiate a friend function template314// after the friend declaration is instantiated during the delayed315// parsing of a member function, but before the friend function has316// been parsed.317namespace rdar12350696 {318 template <class T> struct A {319 void foo() {320 A<int> a;321 }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 327 void test() {328 A<int> b;329 foo(b); // expected-note {{in instantiation}}330 }331}332 333namespace StackUseAfterScope {334template <typename T> class Bar {};335class Foo {336 // Make sure this doesn't crash.337 template <> friend class Bar<int>; // expected-error {{template specialization declaration cannot be a friend}}338 bool aux;339};340}341