summaryrefslogtreecommitdiff
path: root/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp')
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp358
1 files changed, 358 insertions, 0 deletions
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp
new file mode 100644
index 0000000..63f569b
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -0,0 +1,358 @@
+// 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 {{elaborated type refers to a template}}
+ };
+ 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 {
+ 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 {
+ void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
+ };
+
+ template <> class B<float> {
+ 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}}
+}