diff options
Diffstat (limited to 'test/CXX/class.access')
-rw-r--r-- | test/CXX/class.access/class.access.base/p1.cpp | 2 | ||||
-rw-r--r-- | test/CXX/class.access/class.access.base/p5.cpp | 2 | ||||
-rw-r--r-- | test/CXX/class.access/class.access.nest/p1.cpp | 2 | ||||
-rw-r--r-- | test/CXX/class.access/class.friend/p1.cpp | 97 | ||||
-rw-r--r-- | test/CXX/class.access/class.friend/p2-cxx03.cpp | 13 | ||||
-rw-r--r-- | test/CXX/class.access/class.friend/p3-cxx0x.cpp | 29 | ||||
-rw-r--r-- | test/CXX/class.access/class.protected/p1.cpp | 387 | ||||
-rw-r--r-- | test/CXX/class.access/p4.cpp | 99 | ||||
-rw-r--r-- | test/CXX/class.access/p6.cpp | 69 |
9 files changed, 691 insertions, 9 deletions
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp index 1bbcedb9a1e72..09884316f9cd5 100644 --- a/test/CXX/class.access/class.access.base/p1.cpp +++ b/test/CXX/class.access/class.access.base/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // C++0x [class.access.base]p1(a): // If a class is declared to be a base class for another class using diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp index 96037e7de2b04..938d9fbe9bf8a 100644 --- a/test/CXX/class.access/class.access.base/p5.cpp +++ b/test/CXX/class.access/class.access.base/p5.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -faccess-control -verify %s +// RUN: %clang_cc1 -verify %s namespace test0 { struct A { diff --git a/test/CXX/class.access/class.access.nest/p1.cpp b/test/CXX/class.access/class.access.nest/p1.cpp index d2644c6ef4761..eceffcf991bb7 100644 --- a/test/CXX/class.access/class.access.nest/p1.cpp +++ b/test/CXX/class.access/class.access.nest/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // Derived from GNU's std::string namespace test0 { diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 22266cd8f8fcd..991698d5dcca9 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // C++'0x [class.friend] p1: // A friend of a class is a function or class that is given permission to use @@ -192,3 +192,98 @@ namespace test4 { return a == b; // expected-note {{requested here}} } } + + +// PR6174 +namespace test5 { + namespace ns { + class A; + } + + class ns::A { + private: int x; + friend class B; + }; + + namespace ns { + class B { + int test(A *p) { return p->x; } + }; + } +} + +// PR6207 +namespace test6 { + struct A {}; + + struct B { + friend A::A(); + friend A::~A(); + friend A &A::operator=(const A&); + }; +} + +namespace test7 { + template <class T> struct X { + X(); + ~X(); + void foo(); + void bar(); + }; + + class A { + friend void X<int>::foo(); + friend X<int>::X(); + friend X<int>::X(const X&); + + private: + A(); // expected-note 2 {{declared private here}} + }; + + template<> void X<int>::foo() { + A a; + } + + template<> void X<int>::bar() { + A a; // expected-error {{calling a private constructor}} + } + + template<> X<int>::X() { + A a; + } + + template<> X<int>::~X() { + A a; // expected-error {{calling a private constructor}} + } +} + +// Return types, parameters and default arguments to friend functions. +namespace test8 { + class A { + typedef int I; // expected-note 4 {{declared private here}} + static const I x = 0; + friend I f(I i); + template<typename T> friend I g(I i); + }; + + // FIXME: This should be on line 264. + const A::I A::x; // expected-note {{declared private here}} + A::I f(A::I i = A::x) {} + template<typename T> A::I g(A::I i) { + T t; + } + template A::I g<A::I>(A::I i); + + A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}} + template<typename T> A::I g2(A::I i) { // expected-error 2 {{is a private member of}} + T t; + } + template A::I g2<A::I>(A::I i); +} + +// PR6885 +namespace test9 { + class B { + friend class test9; + }; +} diff --git a/test/CXX/class.access/class.friend/p2-cxx03.cpp b/test/CXX/class.access/class.friend/p2-cxx03.cpp new file mode 100644 index 0000000000000..0391c4b989d2e --- /dev/null +++ b/test/CXX/class.access/class.friend/p2-cxx03.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<typename T> +class X0 { + friend T; // expected-warning{{non-class type 'T' cannot be a friend}} +}; + +class X1 { }; +enum E1 { }; +X0<X1> x0a; +X0<X1 *> x0b; +X0<int> x0c; +X0<E1> x0d; + diff --git a/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/test/CXX/class.access/class.friend/p3-cxx0x.cpp new file mode 100644 index 0000000000000..4f55e5339ab2d --- /dev/null +++ b/test/CXX/class.access/class.friend/p3-cxx0x.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s +template<typename T> +class X0 { + friend T; +}; + +class Y1 { }; +enum E1 { }; +X0<Y1> x0a; +X0<Y1 *> x0b; +X0<int> x0c; +X0<E1> x0d; + +template<typename T> +class X1 { + friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}} +}; + +struct Y2 { + struct type { }; +}; + +struct Y3 { + typedef int type; +}; + +X1<Y2> x1a; +X1<Y3> x1b; +X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}} diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp new file mode 100644 index 0000000000000..6ff630c996972 --- /dev/null +++ b/test/CXX/class.access/class.protected/p1.cpp @@ -0,0 +1,387 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + class A { + protected: int x; // expected-note 3 {{declared}} + static int sx; // expected-note 3 {{declared}} + }; + class B : public A { + }; + class C : protected A { // expected-note {{declared}} + }; + class D : private B { // expected-note 3 {{constrained}} + }; + + void test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; // expected-error {{'sx' is a protected member}} + } + void test(B &b) { + (void) b.x; // expected-error {{'x' is a protected member}} + (void) b.sx; // expected-error {{'sx' is a protected member}} + } + void test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} expected-error {{private base class}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } +} + +namespace test1 { + class A { + protected: int x; + static int sx; + static void test(A&); + }; + class B : public A { + static void test(B&); + }; + class C : protected A { + static void test(C&); + }; + class D : private B { + static void test(D&); + }; + + void A::test(A &a) { + (void) a.x; + (void) a.sx; + } + void B::test(B &b) { + (void) b.x; + (void) b.sx; + } + void C::test(C &c) { + (void) c.x; + (void) c.sx; + } + void D::test(D &d) { + (void) d.x; + (void) d.sx; + } +} + +namespace test2 { + class A { + protected: int x; // expected-note 3 {{declared}} + static int sx; + static void test(A&); + }; + class B : public A { + static void test(A&); + }; + class C : protected A { + static void test(A&); + }; + class D : private B { + static void test(A&); + }; + + void A::test(A &a) { + (void) a.x; + (void) a.sx; + } + void B::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } + void C::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } + void D::test(A &a) { + (void) a.x; // expected-error {{'x' is a protected member}} + (void) a.sx; + } +} + +namespace test3 { + class B; + class A { + protected: int x; // expected-note {{declared}} + static int sx; + static void test(B&); + }; + class B : public A { + static void test(B&); + }; + class C : protected A { + static void test(B&); + }; + class D : private B { + static void test(B&); + }; + + void A::test(B &b) { + (void) b.x; + (void) b.sx; + } + void B::test(B &b) { + (void) b.x; + (void) b.sx; + } + void C::test(B &b) { + (void) b.x; // expected-error {{'x' is a protected member}} + (void) b.sx; + } + void D::test(B &b) { + (void) b.x; + (void) b.sx; + } +} + +namespace test4 { + class C; + class A { + protected: int x; // expected-note 2 {{declared}} + static int sx; + static void test(C&); + }; + class B : public A { + static void test(C&); + }; + class C : protected A { // expected-note 4 {{constrained}} expected-note 3 {{declared}} + static void test(C&); + }; + class D : private B { + static void test(C&); + }; + + void A::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void B::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } + void C::test(C &c) { + (void) c.x; + (void) c.sx; + } + void D::test(C &c) { + (void) c.x; // expected-error {{'x' is a protected member}} \ + // expected-error {{protected base class}} + (void) c.sx; // expected-error {{'sx' is a protected member}} + } +} + +namespace test5 { + class D; + class A { + protected: int x; + static int sx; + static void test(D&); + }; + class B : public A { + static void test(D&); + }; + class C : protected A { + static void test(D&); + }; + class D : private B { // expected-note 9 {{constrained}} + static void test(D&); + }; + + void A::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void B::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void C::test(D &d) { + (void) d.x; // expected-error {{'x' is a private member}} \ + // expected-error {{cannot cast}} + (void) d.sx; // expected-error {{'sx' is a private member}} + } + void D::test(D &d) { + (void) d.x; + (void) d.sx; + } +} + +namespace test6 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{declared}} + void foo(long); + static void foo(Static); + + static void test(A&); + }; + class B : public A { + static void test(A&); + }; + class C : protected A { + static void test(A&); + }; + class D : private B { + static void test(A&); + }; + + void A::test(A &a) { + a.foo(10); + a.foo(Static()); + } + void B::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } + void C::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } + void D::test(A &a) { + a.foo(10); // expected-error {{'foo' is a protected member}} + a.foo(Static()); + } +} + +namespace test7 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{declared}} + void foo(long); + static void foo(Static); + + static void test(); + }; + class B : public A { + static void test(); + }; + class C : protected A { + static void test(); + }; + class D : private B { + static void test(); + }; + + void A::test() { + void (A::*x)(int) = &A::foo; + void (*sx)(Static) = &A::foo; + } + void B::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } + void C::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } + void D::test() { + void (A::*x)(int) = &A::foo; // expected-error {{'foo' is a protected member}} + void (*sx)(Static) = &A::foo; + } +} + +namespace test8 { + class Static {}; + class A { + protected: + void foo(int); // expected-note 3 {{declared}} + void foo(long); + static void foo(Static); + + static void test(); + }; + class B : public A { + static void test(); + }; + class C : protected A { + static void test(); + }; + class D : private B { + static void test(); + }; + void call(void (A::*)(int)); + void calls(void (*)(Static)); + + void A::test() { + call(&A::foo); + calls(&A::foo); + } + void B::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } + void C::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } + void D::test() { + call(&A::foo); // expected-error {{'foo' is a protected member}} + calls(&A::foo); + } +} + +namespace test9 { + class A { + protected: int foo(); // expected-note 8 {{declared}} + }; + + class B : public A { + friend class D; + }; + + class C : protected B { // expected-note {{declared}} \ + // expected-note 6 {{constrained}} + }; + + class D : public A { + static void test(A &a) { + a.foo(); // expected-error {{'foo' is a protected member}} + a.A::foo(); // expected-error {{'foo' is a protected member}} + a.B::foo(); + a.C::foo(); // expected-error {{'foo' is a protected member}} + } + + static void test(B &b) { + b.foo(); + b.A::foo(); // expected-error {{'foo' is a protected member}} + b.B::foo(); + b.C::foo(); // expected-error {{'foo' is a protected member}} + } + + static void test(C &c) { + c.foo(); // expected-error {{'foo' is a protected member}} \ + // expected-error {{cannot cast}} + c.A::foo(); // expected-error {{'foo' is a protected member}} \ + // expected-error {{'A' is a protected member}} \ + // expected-error {{cannot cast}} + c.B::foo(); // expected-error {{'B' is a protected member}} \ + // expected-error {{cannot cast}} + c.C::foo(); // expected-error {{'foo' is a protected member}} \ + // expected-error {{cannot cast}} + } + + static void test(D &d) { + d.foo(); + d.A::foo(); + d.B::foo(); + d.C::foo(); // expected-error {{'foo' is a protected member}} + } + }; +} + +namespace test10 { + template<typename T> class A { + protected: + int foo(); + int foo() const; + + ~A() { foo(); } + }; + + template class A<int>; +} diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 3bbdbab8d516d..1cd8966136795 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // C++0x [class.access]p4: @@ -88,13 +88,24 @@ namespace test1 { namespace test2 { class A { private: - A(); // expected-note {{declared private here}} + A(); // expected-note 3 {{declared private here}} static A foo; }; A a; // expected-error {{calling a private constructor}} A A::foo; // okay + + class B : A { }; // expected-error {{base class 'test2::A' has private constructor}} + B b; + + class C : virtual A { + public: + C(); + }; + + class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private constructor}} + D d; } // Implicit destructor calls. @@ -191,13 +202,13 @@ namespace test5 { void operator=(const A &); // expected-note 2 {{declared private here}} }; - class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}} + class Test1 { A a; }; // expected-error {{private member}} void test1() { Test1 a; a = Test1(); } - class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}} + class Test2 : A {}; // expected-error {{private member}} void test2() { Test2 a; a = Test2(); @@ -327,3 +338,83 @@ namespace test13 { (void) d->x; } } + +// Destructors for temporaries. +namespace test14 { + class A { + private: ~A(); // expected-note {{declared private here}} + }; + A foo(); + + void test() { + foo(); // expected-error {{temporary of type 'test14::A' has private destructor}} + } + + class X { + ~X(); // expected-note {{declared private here}} + }; + + struct Y1 { + operator X(); + }; + + void g() { + const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}} + } +} + +// PR 7024 +namespace test15 { + template <class T> class A { + private: + int private_foo; // expected-note {{declared private here}} + static int private_sfoo; // expected-note {{declared private here}} + protected: + int protected_foo; // expected-note 4 {{declared protected here}} + static int protected_sfoo; // expected-note 3 {{declared protected here}} + + int test1(A<int> &a) { + return a.private_foo; // expected-error {{private member}} + } + + int test2(A<int> &a) { + return a.private_sfoo; // expected-error {{private member}} + } + + int test3(A<int> &a) { + return a.protected_foo; // expected-error {{protected member}} + } + + int test4(A<int> &a) { + return a.protected_sfoo; // expected-error {{protected member}} + } + }; + + template class A<int>; + template class A<long>; // expected-note 4 {{in instantiation}} + + template <class T> class B : public A<T> { + // TODO: These first two accesses can be detected as ill-formed at + // definition time because they're member accesses and A<int> can't + // be a subclass of B<T> for any T. + + int test1(A<int> &a) { + return a.protected_foo; // expected-error 2 {{protected member}} + } + + int test2(A<int> &a) { + return a.protected_sfoo; // expected-error {{protected member}} + } + + int test3(B<int> &b) { + return b.protected_foo; // expected-error {{protected member}} + } + + int test4(B<int> &b) { + return b.protected_sfoo; // expected-error {{protected member}} + } + }; + + template class B<int>; // expected-note {{in instantiation}} + template class B<long>; // expected-note 4 {{in instantiation}} +} diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp index aaf510a6d11fd..734a4d8c48692 100644 --- a/test/CXX/class.access/p6.cpp +++ b/test/CXX/class.access/p6.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // C++0x [class.access]p6: // All access controls in [class.access] affect the ability to @@ -52,3 +52,70 @@ namespace test1 { A apriv = priv; // expected-error {{private constructor}} } } + +// PR6967 +namespace test2 { + class A { + public: + template <class T> static void set(T &t, typename T::type v) { + t.value = v; + } + template <class T> static typename T::type get(const T &t) { + return t.value; + } + }; + + class B { + friend class A; + + private: + typedef int type; + type value; + }; + + int test() { + B b; + A::set(b, 0); + return A::get(b); + } +} + +namespace test3 { + class Green {}; class Blue {}; + + // We have to wrap this in a class because a partial specialization + // isn't actually in the context of the template. + struct Outer { + template <class T, class Nat> class A { + }; + }; + + template <class T> class Outer::A<T, typename T::nature> { + public: + static void foo(); + }; + + class B { + private: typedef Green nature; + friend class Outer; + }; + + void test() { + Outer::A<B, Green>::foo(); + Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo'}} + } +} + +namespace test4 { + template <class T> class A { + private: typedef int type; + template <class U> friend void foo(U &, typename U::type); + }; + + template <class U> void foo(U &, typename U::type) {} + + void test() { + A<int> a; + foo(a, 0); + } +} |