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 {{elaborated type refers to a template}}
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