| 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 | |