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: |
8 | Num(T value) : value_(value) {} |
9 | T get() const { return value_; } |
10 | |
11 | template <typename U> struct Rep { |
12 | U count_; |
13 | Rep(U count) : count_(count) {} |
14 | |
15 | 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 | |
23 | friend Num operator+(const Num &a, const Num &b) { |
24 | return a.value_ + b.value_; |
25 | } |
26 | |
27 | 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 | |
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 | |
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 | }; |
66 | template <typename T> bool has(const A &x) { |
67 | return x.b; |
68 | } |
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 { |
80 | bool check(A *a) { |
81 | return a->b; |
82 | } |
83 | }; |
84 | template <typename T> class HasNotChecker { |
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 { |
104 | static T compute(Bool b) { |
105 | return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} |
106 | } |
107 | }; |
108 | |
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 { |
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 { |
164 | int foo(A<int> &a) { |
165 | return a.x; |
166 | } |
167 | }; |
168 | |
169 | class C { |
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 | |
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 | |
199 | int foo(B *b) { |
200 | return b->x; |
201 | } |
202 | |
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 | |
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; |
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; |
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 { |
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: |
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: |
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: |
330 | void foo() { return A<float>::foo(); } |
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 | |
342 | template<class T> void f(X<T> *x) { |
343 | x->member = 0; |
344 | } |
345 | |
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 { |
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}} |
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 | |