diff options
Diffstat (limited to 'test/CXX/class.access')
| -rw-r--r-- | test/CXX/class.access/class.access.base/p1.cpp | 45 | ||||
| -rw-r--r-- | test/CXX/class.access/p4.cpp | 114 | ||||
| -rw-r--r-- | test/CXX/class.access/p6.cpp | 54 |
3 files changed, 190 insertions, 23 deletions
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp index fd0d9f68e1e2..1bbcedb9a1e7 100644 --- a/test/CXX/class.access/class.access.base/p1.cpp +++ b/test/CXX/class.access/class.access.base/p1.cpp @@ -54,13 +54,13 @@ namespace test0 { // of the base class are accessible as protected members of the // derived class. namespace test1 { - class Base { // expected-note 6 {{constrained by protected inheritance}} - public: int pub; static int spub; // expected-note 2 {{constrained by protected inheritance}} + class Base { + public: int pub; static int spub; protected: int prot; static int sprot; // expected-note 4 {{declared protected here}} private: int priv; static int spriv; // expected-note 8 {{declared private here}} }; - class Test : protected Base { + class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}} void test() { pub++; spub++; @@ -79,19 +79,19 @@ namespace test1 { }; void test(Test *t) { - t->pub++; // expected-error {{protected member}} + t->pub++; // expected-error {{protected member}} expected-error {{protected base class}} t->spub++; // expected-error {{protected member}} - t->prot++; // expected-error {{protected member}} + t->prot++; // expected-error {{protected member}} expected-error {{protected base class}} t->sprot++; // expected-error {{protected member}} - t->priv++; // expected-error {{private member}} + t->priv++; // expected-error {{private member}} expected-error {{protected base class}} t->spriv++; // expected-error {{private member}} // Two possible errors here: one for Base, one for the member - t->Base::pub++; // expected-error {{protected member}} + t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}} t->Base::spub++; // expected-error {{protected member}} - t->Base::prot++; // expected-error 2 {{protected member}} + t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}} t->Base::sprot++; // expected-error 2 {{protected member}} - t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} + t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}} t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}} } } @@ -102,21 +102,20 @@ namespace test1 { // the base class are accessible as private members of the derived // class. namespace test2 { - class Base { //expected-note 6 {{constrained by private inheritance}} + class Base { public: - int pub; // expected-note {{constrained by private inheritance}} - static int spub; // expected-note {{constrained by private inheritance}} + int pub; + static int spub; protected: - int prot; // expected-note {{constrained by private inheritance}} \ - // expected-note {{declared protected here}} - static int sprot; // expected-note {{constrained by private inheritance}} \ - // expected-note {{declared protected here}} + int prot; // expected-note {{declared protected here}} + static int sprot; // expected-note {{declared protected here}} private: int priv; // expected-note 4 {{declared private here}} static int spriv; // expected-note 4 {{declared private here}} }; - class Test : private Base { // expected-note 6 {{'private' inheritance specifier here}} + class Test : private Base { // expected-note 6 {{declared private here}} \ + // expected-note 10 {{constrained by private inheritance here}} void test() { pub++; spub++; @@ -135,18 +134,18 @@ namespace test2 { }; void test(Test *t) { - t->pub++; // expected-error {{private member}} expected-error {{inaccessible base class}} + t->pub++; // expected-error {{private member}} expected-error {{private base class}} t->spub++; // expected-error {{private member}} - t->prot++; // expected-error {{private member}} expected-error {{inaccessible base class}} + t->prot++; // expected-error {{private member}} expected-error {{private base class}} t->sprot++; // expected-error {{private member}} - t->priv++; // expected-error {{private member}} expected-error {{inaccessible base class}} + t->priv++; // expected-error {{private member}} expected-error {{private base class}} t->spriv++; // expected-error {{private member}} - t->Base::pub++; // expected-error {{private member}} expected-error {{inaccessible base class}} + t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}} t->Base::spub++; // expected-error {{private member}} - t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{inaccessible base class}} + t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}} t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}} - t->Base::priv++; // expected-error 2 {{private member}} expected-error {{inaccessible base class}} + t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}} t->Base::spriv++; // expected-error 2 {{private member}} } } diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp new file mode 100644 index 000000000000..7aa614cd8b1a --- /dev/null +++ b/test/CXX/class.access/p4.cpp @@ -0,0 +1,114 @@ +// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s + +// C++0x [class.access]p4: + +// Access control is applied uniformly to all names, whether the +// names are referred to from declarations or expressions. In the +// case of overloaded function names, access control is applied to +// the function selected by overload resolution. + +class Public {} PublicInst; +class Protected {} ProtectedInst; +class Private {} PrivateInst; + +namespace test0 { + class A { + public: + void foo(Public&); + protected: + void foo(Protected&); // expected-note 2 {{declared protected here}} + private: + void foo(Private&); // expected-note 2 {{declared private here}} + }; + + void test(A *op) { + op->foo(PublicInst); + op->foo(ProtectedInst); // expected-error {{'foo' is a protected member}} + op->foo(PrivateInst); // expected-error {{'foo' is a private member}} + + void (A::*a)(Public&) = &A::foo; + void (A::*b)(Protected&) = &A::foo; // expected-error {{'foo' is a protected member}} + void (A::*c)(Private&) = &A::foo; // expected-error {{'foo' is a private member}} + } +} + +// Member operators. +namespace test1 { + class A { + public: + void operator+(Public&); + void operator[](Public&); + void operator()(Public&); + typedef void (*PublicSurrogate)(Public&); + operator PublicSurrogate() const; + protected: + void operator+(Protected&); // expected-note {{declared protected here}} + void operator[](Protected&); // expected-note {{declared protected here}} + void operator()(Protected&); // expected-note {{declared protected here}} + typedef void (*ProtectedSurrogate)(Protected&); + operator ProtectedSurrogate() const; // expected-note {{declared protected here}} + private: + void operator+(Private&); // expected-note {{declared private here}} + void operator[](Private&); // expected-note {{declared private here}} + void operator()(Private&); // expected-note {{declared private here}} + void operator-(); // expected-note {{declared private here}} + typedef void (*PrivateSurrogate)(Private&); + operator PrivateSurrogate() const; // expected-note {{declared private here}} + }; + void operator+(const A &, Public&); + void operator+(const A &, Protected&); + void operator+(const A &, Private&); + void operator-(const A &); + + void test(A &a, Public &pub, Protected &prot, Private &priv) { + a + pub; + a + prot; // expected-error {{'operator+' is a protected member}} + a + priv; // expected-error {{'operator+' is a private member}} + a[pub]; + a[prot]; // expected-error {{'operator[]' is a protected member}} + a[priv]; // expected-error {{'operator[]' is a private member}} + a(pub); + a(prot); // expected-error {{'operator()' is a protected member}} + a(priv); // expected-error {{'operator()' is a private member}} + -a; // expected-error {{'operator-' is a private member}} + + const A &ca = a; + ca + pub; + ca + prot; + ca + priv; + -ca; + // These are all surrogate calls + ca(pub); + ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}} + ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}} + } +} + +// Implicit constructor calls. +namespace test2 { + class A { + private: + A(); // expected-note {{declared private here}} + + static A foo; + }; + + A a; // expected-error {{calling a private constructor}} + A A::foo; // okay +} + +// Implicit destructor calls. +namespace test3 { + class A{ + private: + ~A(); // expected-note 3 {{declared private here}} + static A foo; + }; + + A a; // expected-error {{'~A' is a private member}} + A A::foo; + + void foo(A param) { // expected-error {{'~A' is a private member}} + A local; // expected-error {{'~A' is a private member}} + } +} diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp new file mode 100644 index 000000000000..aaf510a6d11f --- /dev/null +++ b/test/CXX/class.access/p6.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s + +// C++0x [class.access]p6: +// All access controls in [class.access] affect the ability to +// access a class member name from a particular scope. For purposes +// of access control, the base-specifiers of a class and the +// definitions of class members that appear outside of the class +// definition are considered to be within the scope of that +// class. In particular, access controls apply as usual to member +// names accessed as part of a function return type, even though it +// is not possible to determine the access privileges of that use +// without first parsing the rest of the function +// declarator. Similarly, access control for implicit calls to the +// constructors, the conversion functions, or the destructor called +// to create and destroy a static data member is performed as if +// these calls appeared in the scope of the member's class. + +struct Public {}; struct Protected {}; struct Private {}; + +namespace test0 { + class A { + typedef int type; // expected-note {{declared private here}} + type foo(); + }; + + A::type foo() { } // expected-error {{'type' is a private member}} + A::type A::foo() { } +} + +// conversion decls +namespace test1 { + class A { + public: + A(); + operator Public (); + A(Public); + protected: + operator Protected (); // expected-note {{declared protected here}} + A(Protected); // expected-note {{declared protected here}} + private: + operator Private (); // expected-note {{declared private here}} + A(Private); // expected-note {{declared private here}} + }; + + void test() { + A a; + Public pub = a; + Protected prot = a; // expected-error {{'operator Protected' is a protected member}} + Private priv = a; // expected-error {{'operator Private' is a private member}} + A apub = pub; + A aprot = prot; // expected-error {{protected constructor}} + A apriv = priv; // expected-error {{private constructor}} + } +} |
