1 // RUN: %clang_cc1 -verify -emit-llvm-only %s
2 
3 namespace test0 {
4 template <typename T> struct Num {
5   T value_;
6 
7 public:
Numtest0::Num8   Num(T value) : value_(value) {}
gettest0::Num9   T get() const { return value_; }
10 
11   template <typename U> struct Rep {
12     U count_;
Reptest0::Num::Rep13     Rep(U count) : count_(count) {}
14 
operator *test0::Num15     friend Num operator*(const Num &a, const Rep &n) {
16       Num x = 0;
17       for (U count = n.count_; count; --count)
18         x += a;
19       return x;
20     }
21   };
22 
operator +(const Num & a,const Num & b)23   friend Num operator+(const Num &a, const Num &b) {
24     return a.value_ + b.value_;
25   }
26 
operator +=test0::Num27   Num& operator+=(const Num& b) {
28     value_ += b.value_;
29     return *this;
30   }
31 
32   class Representation {};
33   friend class Representation;
34 };
35 
36 class A {
37   template <typename T> friend bool iszero(const A &a) throw();
38 };
39 
40 template <class T> class B_iterator;
41 template <class T> class B {
42   friend class B_iterator<T>;
43 };
44 
calc1()45 int calc1() {
46   Num<int> left = -1;
47   Num<int> right = 1;
48   Num<int> result = left + right;
49   return result.get();
50 }
51 
calc2()52 int calc2() {
53   Num<int> x = 3;
54   Num<int>::Rep<char> n = (char) 10;
55   Num<int> result = x * n;
56   return result.get();
57 }
58 }
59 
60 // Reduced from GNU <locale>
61 namespace test1 {
62   class A {
63     bool b; // expected-note {{declared private here}}
64     template <typename T> friend bool has(const A&);
65   };
has(const A & x)66   template <typename T> bool has(const A &x) {
67     return x.b;
68   }
hasnot(const A & x)69   template <typename T> bool hasnot(const A &x) {
70     return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
71   }
72 }
73 
74 namespace test2 {
75   class A {
76     bool b; // expected-note {{declared private here}}
77     template <typename T> friend class HasChecker;
78   };
79   template <typename T> class HasChecker {
check(A * a)80     bool check(A *a) {
81       return a->b;
82     }
83   };
84   template <typename T> class HasNotChecker {
check(A * a)85     bool check(A *a) {
86       return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
87     }
88   };
89 }
90 
91 namespace test3 {
92   class Bool;
93   template <class T> class User;
94   template <class T> T transform(class Bool, T);
95 
96   class Bool {
97     friend class User<bool>;
98     friend bool transform<>(Bool, bool);
99 
100     bool value; // expected-note 2 {{declared private here}}
101   };
102 
103   template <class T> class User {
compute(Bool b)104     static T compute(Bool b) {
105       return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
106     }
107   };
108 
transform(Bool b,T value)109   template <class T> T transform(Bool b, T value) {
110     if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
111       return value;
112     return value + 1;
113   }
114 
115   template bool transform(Bool, bool);
116   template int transform(Bool, int); // expected-note {{requested here}}
117 
118   template class User<bool>;
119   template class User<int>; // expected-note {{requested here}}
120 }
121 
122 namespace test4 {
123   template <class T> class A {
124     template <class T0> friend class B;
125     bool foo(const A<T> *) const;
126   };
127 
128   template <class T> class B {
bar(const A<T> * a,const A<T> * b)129     bool bar(const A<T> *a, const A<T> *b) {
130       return a->foo(b);
131     }
132   };
133 
134   template class B<int>;
135 }
136 
137 namespace test5 {
138   template <class T, class U=int> class A {};
139   template <class T> class B {
140     template <class X, class Y> friend class A;
141   };
142   template class B<int>;
143   template class A<int>;
144 }
145 
146 namespace Dependent {
147   template<typename T, typename Traits> class X;
148   template<typename T, typename Traits>
149   X<T, Traits> operator+(const X<T, Traits>&, const T*);
150 
151   template<typename T, typename Traits> class X {
152     typedef typename Traits::value_type value_type;
153     friend X operator+<>(const X&, const value_type*);
154   };
155 }
156 
157 namespace test7 {
158   template <class T> class A { // expected-note {{declared here}}
159     friend class B;
160     int x; // expected-note {{declared private here}}
161   };
162 
163   class B {
foo(A<int> & a)164     int foo(A<int> &a) {
165       return a.x;
166     }
167   };
168 
169   class C {
foo(A<int> & a)170     int foo(A<int> &a) {
171       return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}}
172     }
173   };
174 
175   // This shouldn't crash.
176   template <class T> class D {
177     friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}}
178   };
179   template class D<int>;
180 }
181 
182 namespace test8 {
183   template <class N> class A {
184     static int x;
185     template <class T> friend void foo();
186   };
187   template class A<int>;
188 
foo()189   template <class T> void foo() {
190     A<int>::x = 0;
191   }
192   template void foo<int>();
193 }
194 
195 namespace test9 {
196   template <class T> class A {
197     class B; class C;
198 
foo(B * b)199     int foo(B *b) {
200       return b->x;
201     }
202 
foo(C * c)203     int foo(C *c) {
204       return c->x; // expected-error {{'x' is a private member}}
205     }
206 
207     class B {
208       int x;
209       friend int A::foo(B*);
210     };
211 
212     class C {
213       int x; // expected-note {{declared private here}}
214     };
215   };
216 
217   template class A<int>; // expected-note {{in instantiation}}
218 }
219 
220 namespace test10 {
221   template <class T> class A;
222   template <class T> A<T> bar(const T*, const A<T>&);
223   template <class T> class A {
224   private:
225     void foo(); // expected-note {{declared private here}}
226     friend A bar<>(const T*, const A<T>&);
227   };
228 
bar(const T * l,const A<T> & r)229   template <class T> A<T> bar(const T *l, const A<T> &r) {
230     A<T> l1;
231     l1.foo();
232 
233     A<char> l2;
234     l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}}
235 
236     return l1;
237   }
238 
239   template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}}
240 }
241 
242 // PR6752: this shouldn't crash.
243 namespace test11 {
244   struct Foo {
245     template<class A>
246     struct IteratorImpl {
247       template<class T> friend class IteratorImpl;
248     };
249   };
250 
251   template struct Foo::IteratorImpl<int>;
252   template struct Foo::IteratorImpl<long>;
253 }
254 
255 // PR6827
256 namespace test12 {
257   template <typename T> class Foo;
foo(T * t)258   template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
259 
260   template <typename T> class Foo {
261   public:
262     Foo(T*);
263     friend Foo<T> foo<T>(T*);
264   private:
265     Foo(T*, bool); // expected-note {{declared private here}}
266   };
267 
268   // Should work.
269   int globalInt;
270   Foo<int> f = foo(&globalInt);
271 
272   // Shouldn't work.
273   long globalLong;
foo(long * t)274   template <> Foo<long> foo(long *t) {
275     Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}}
276     return Foo<long>(t, true);
277   }
278 }
279 
280 // PR6514
281 namespace test13 {
282   template <int N, template <int> class Temp>
283   class Role : public Temp<N> {
284     friend class Temp<N>;
285     int x;
286   };
287 
288   template <int N> class Foo {
foo(Role<N,test13::Foo> & role)289     void foo(Role<N, test13::Foo> &role) {
290       (void) role.x;
291     }
292   };
293 
294   template class Foo<0>;
295 }
296 
297 namespace test14 {
298   template <class T> class B;
299   template <class T> class A {
300     friend void B<T>::foo();
301     static void foo(); // expected-note {{declared private here}}
302   };
303 
304   template <class T> class B {
305   public:
foo()306     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}
307   };
308 
309   template class B<int>; // expected-note {{in instantiation}}
310 }
311 
312 namespace test15 {
313   template <class T> class B;
314   template <class T> class A {
315     friend void B<T>::foo();
316 
317     // This shouldn't be misrecognized as a templated-scoped reference.
318     template <class U> friend void B<T>::bar(U);
319 
320     static void foo(); // expected-note {{declared private here}}
321   };
322 
323   template <class T> class B {
324   public:
foo()325     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
326   };
327 
328   template <> class B<float> {
329   public:
foo()330     void foo() { return A<float>::foo(); }
bar(U u)331     template <class U> void bar(U u) {
332       (void) A<float>::foo();
333     }
334   };
335 
336   template class B<int>; // expected-note {{in instantiation}}
337 }
338 
339 namespace PR10913 {
340   template<class T> class X;
341 
f(X<T> * x)342   template<class T> void f(X<T> *x) {
343     x->member = 0;
344   }
345 
f2(X<T> * x)346   template<class U, class T> void f2(X<T> *x) {
347     x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}}
348   }
349 
350   template<class T> class X {
351     friend void f<T>(X<T> *x);
352     friend void f2<T>(X<int> *x);
353 
354   protected:
355     int member; // expected-note{{declared protected here}}
356   };
357 
358   template void f(X<int> *);
359   template void f2<int>(X<int> *);
360   template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}}
361 }
362 
363 namespace test16 {
364 template <class T> struct foo {}; // expected-note{{candidate ignored: not a function template}}
365 template <class T> class A {
366   friend void foo<T>(); // expected-error{{no candidate function template was found for dependent friend function template specialization}}
367 };
368 }
369 
370 namespace test17 {
371 namespace ns {
foo()372 template <class T> void foo() {} // expected-note{{candidate ignored: not a member of the enclosing namespace; did you mean to explicitly qualify the specialization?}}
373 }
374 using ns::foo;
375 template <class T> struct A {
376   friend void foo<T>() {} // expected-error{{no candidate function template was found for dependent friend function template specialization}}
377 };
378 }
379 
380 namespace test18 {
381 namespace ns1 { template <class T> struct foo {}; } // expected-note{{candidate ignored: not a function template}}
foo()382 namespace ns2 { void foo() {} } // expected-note{{candidate ignored: not a function template}}
383 using ns1::foo; // expected-note {{found by name lookup}}
384 using ns2::foo; // expected-note {{found by name lookup}}
385 
386 template <class T> class A {
387   friend void foo<T>() {} // expected-error {{ambiguous}} expected-error{{no candidate function template was found for dependent friend function template specialization}}
388 };
389 }
390