| // RUN: %clang_cc1 -verify -emit-llvm-only %s |
| |
| namespace test0 { |
| template <typename T> struct Num { |
| T value_; |
| |
| public: |
| Num(T value) : value_(value) {} |
| T get() const { return value_; } |
| |
| template <typename U> struct Rep { |
| U count_; |
| Rep(U count) : count_(count) {} |
| |
| friend Num operator*(const Num &a, const Rep &n) { |
| Num x = 0; |
| for (U count = n.count_; count; --count) |
| x += a; |
| return x; |
| } |
| }; |
| |
| friend Num operator+(const Num &a, const Num &b) { |
| return a.value_ + b.value_; |
| } |
| |
| Num& operator+=(const Num& b) { |
| value_ += b.value_; |
| return *this; |
| } |
| |
| class Representation {}; |
| friend class Representation; |
| }; |
| |
| class A { |
| template <typename T> friend bool iszero(const A &a) throw(); |
| }; |
| |
| template <class T> class B_iterator; |
| template <class T> class B { |
| friend class B_iterator<T>; |
| }; |
| |
| int calc1() { |
| Num<int> left = -1; |
| Num<int> right = 1; |
| Num<int> result = left + right; |
| return result.get(); |
| } |
| |
| int calc2() { |
| Num<int> x = 3; |
| Num<int>::Rep<char> n = (char) 10; |
| Num<int> result = x * n; |
| return result.get(); |
| } |
| } |
| |
| // Reduced from GNU <locale> |
| namespace test1 { |
| class A { |
| bool b; // expected-note {{declared private here}} |
| template <typename T> friend bool has(const A&); |
| }; |
| template <typename T> bool has(const A &x) { |
| return x.b; |
| } |
| template <typename T> bool hasnot(const A &x) { |
| return x.b; // expected-error {{'b' is a private member of 'test1::A'}} |
| } |
| } |
| |
| namespace test2 { |
| class A { |
| bool b; // expected-note {{declared private here}} |
| template <typename T> friend class HasChecker; |
| }; |
| template <typename T> class HasChecker { |
| bool check(A *a) { |
| return a->b; |
| } |
| }; |
| template <typename T> class HasNotChecker { |
| bool check(A *a) { |
| return a->b; // expected-error {{'b' is a private member of 'test2::A'}} |
| } |
| }; |
| } |
| |
| namespace test3 { |
| class Bool; |
| template <class T> class User; |
| template <class T> T transform(class Bool, T); |
| |
| class Bool { |
| friend class User<bool>; |
| friend bool transform<>(Bool, bool); |
| |
| bool value; // expected-note 2 {{declared private here}} |
| }; |
| |
| template <class T> class User { |
| static T compute(Bool b) { |
| return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} |
| } |
| }; |
| |
| template <class T> T transform(Bool b, T value) { |
| if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}} |
| return value; |
| return value + 1; |
| } |
| |
| template bool transform(Bool, bool); |
| template int transform(Bool, int); // expected-note {{requested here}} |
| |
| template class User<bool>; |
| template class User<int>; // expected-note {{requested here}} |
| } |
| |
| namespace test4 { |
| template <class T> class A { |
| template <class T0> friend class B; |
| bool foo(const A<T> *) const; |
| }; |
| |
| template <class T> class B { |
| bool bar(const A<T> *a, const A<T> *b) { |
| return a->foo(b); |
| } |
| }; |
| |
| template class B<int>; |
| } |
| |
| namespace test5 { |
| template <class T, class U=int> class A {}; |
| template <class T> class B { |
| template <class X, class Y> friend class A; |
| }; |
| template class B<int>; |
| template class A<int>; |
| } |
| |
| namespace Dependent { |
| template<typename T, typename Traits> class X; |
| template<typename T, typename Traits> |
| X<T, Traits> operator+(const X<T, Traits>&, const T*); |
| |
| template<typename T, typename Traits> class X { |
| typedef typename Traits::value_type value_type; |
| friend X operator+<>(const X&, const value_type*); |
| }; |
| } |
| |
| namespace test7 { |
| template <class T> class A { // expected-note {{declared here}} |
| friend class B; |
| int x; // expected-note {{declared private here}} |
| }; |
| |
| class B { |
| int foo(A<int> &a) { |
| return a.x; |
| } |
| }; |
| |
| class C { |
| int foo(A<int> &a) { |
| return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}} |
| } |
| }; |
| |
| // This shouldn't crash. |
| template <class T> class D { |
| friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}} |
| }; |
| template class D<int>; |
| } |
| |
| namespace test8 { |
| template <class N> class A { |
| static int x; |
| template <class T> friend void foo(); |
| }; |
| template class A<int>; |
| |
| template <class T> void foo() { |
| A<int>::x = 0; |
| } |
| template void foo<int>(); |
| } |
| |
| namespace test9 { |
| template <class T> class A { |
| class B; class C; |
| |
| int foo(B *b) { |
| return b->x; |
| } |
| |
| int foo(C *c) { |
| return c->x; // expected-error {{'x' is a private member}} |
| } |
| |
| class B { |
| int x; |
| friend int A::foo(B*); |
| }; |
| |
| class C { |
| int x; // expected-note {{declared private here}} |
| }; |
| }; |
| |
| template class A<int>; // expected-note {{in instantiation}} |
| } |
| |
| namespace test10 { |
| template <class T> class A; |
| template <class T> A<T> bar(const T*, const A<T>&); |
| template <class T> class A { |
| private: |
| void foo(); // expected-note {{declared private here}} |
| friend A bar<>(const T*, const A<T>&); |
| }; |
| |
| template <class T> A<T> bar(const T *l, const A<T> &r) { |
| A<T> l1; |
| l1.foo(); |
| |
| A<char> l2; |
| l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}} |
| |
| return l1; |
| } |
| |
| template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}} |
| } |
| |
| // PR6752: this shouldn't crash. |
| namespace test11 { |
| struct Foo { |
| template<class A> |
| struct IteratorImpl { |
| template<class T> friend class IteratorImpl; |
| }; |
| }; |
| |
| template struct Foo::IteratorImpl<int>; |
| template struct Foo::IteratorImpl<long>; |
| } |
| |
| // PR6827 |
| namespace test12 { |
| template <typename T> class Foo; |
| template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); } |
| |
| template <typename T> class Foo { |
| public: |
| Foo(T*); |
| friend Foo<T> foo<T>(T*); |
| private: |
| Foo(T*, bool); // expected-note {{declared private here}} |
| }; |
| |
| // Should work. |
| int globalInt; |
| Foo<int> f = foo(&globalInt); |
| |
| // Shouldn't work. |
| long globalLong; |
| template <> Foo<long> foo(long *t) { |
| Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}} |
| return Foo<long>(t, true); |
| } |
| } |
| |
| // PR6514 |
| namespace test13 { |
| template <int N, template <int> class Temp> |
| class Role : public Temp<N> { |
| friend class Temp<N>; |
| int x; |
| }; |
| |
| template <int N> class Foo { |
| void foo(Role<N, test13::Foo> &role) { |
| (void) role.x; |
| } |
| }; |
| |
| template class Foo<0>; |
| } |
| |
| namespace test14 { |
| template <class T> class B; |
| template <class T> class A { |
| friend void B<T>::foo(); |
| static void foo(); // expected-note {{declared private here}} |
| }; |
| |
| template <class T> class B { |
| public: |
| void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}} |
| }; |
| |
| template class B<int>; // expected-note {{in instantiation}} |
| } |
| |
| namespace test15 { |
| template <class T> class B; |
| template <class T> class A { |
| friend void B<T>::foo(); |
| |
| // This shouldn't be misrecognized as a templated-scoped reference. |
| template <class U> friend void B<T>::bar(U); |
| |
| static void foo(); // expected-note {{declared private here}} |
| }; |
| |
| template <class T> class B { |
| public: |
| void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}} |
| }; |
| |
| template <> class B<float> { |
| public: |
| void foo() { return A<float>::foo(); } |
| template <class U> void bar(U u) { |
| (void) A<float>::foo(); |
| } |
| }; |
| |
| template class B<int>; // expected-note {{in instantiation}} |
| } |
| |
| namespace PR10913 { |
| template<class T> class X; |
| |
| template<class T> void f(X<T> *x) { |
| x->member = 0; |
| } |
| |
| template<class U, class T> void f2(X<T> *x) { |
| x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}} |
| } |
| |
| template<class T> class X { |
| friend void f<T>(X<T> *x); |
| friend void f2<T>(X<int> *x); |
| |
| protected: |
| int member; // expected-note{{declared protected here}} |
| }; |
| |
| template void f(X<int> *); |
| template void f2<int>(X<int> *); |
| template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}} |
| } |
| |
| namespace test16 { |
| template <class T> struct foo {}; // expected-note{{candidate ignored: not a function template}} |
| template <class T> class A { |
| friend void foo<T>(); // expected-error{{no candidate function template was found for dependent friend function template specialization}} |
| }; |
| } |
| |
| namespace test17 { |
| namespace ns { |
| template <class T> void foo() {} // expected-note{{candidate ignored: not a member of the enclosing namespace; did you mean to explicitly qualify the specialization?}} |
| } |
| using ns::foo; |
| template <class T> struct A { |
| friend void foo<T>() {} // expected-error{{no candidate function template was found for dependent friend function template specialization}} |
| }; |
| } |
| |
| namespace test18 { |
| namespace ns1 { template <class T> struct foo {}; } // expected-note{{candidate ignored: not a function template}} |
| namespace ns2 { void foo() {} } // expected-note{{candidate ignored: not a function template}} |
| using ns1::foo; // expected-note {{found by name lookup}} |
| using ns2::foo; // expected-note {{found by name lookup}} |
| |
| template <class T> class A { |
| friend void foo<T>() {} // expected-error {{ambiguous}} expected-error{{no candidate function template was found for dependent friend function template specialization}} |
| }; |
| } |