summaryrefslogtreecommitdiffstats
path: root/test/CXX/class.access
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/class.access')
-rw-r--r--test/CXX/class.access/class.access.base/p5.cpp23
-rw-r--r--test/CXX/class.access/class.friend/p3-cxx0x.cpp7
-rw-r--r--test/CXX/class.access/class.protected/p1.cpp7
3 files changed, 34 insertions, 3 deletions
diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp
index 255fbfc..5b08a86 100644
--- a/test/CXX/class.access/class.access.base/p5.cpp
+++ b/test/CXX/class.access/class.access.base/p5.cpp
@@ -72,4 +72,27 @@ namespace test3 {
};
}
+// Don't crash. <rdar://12926092>
+// Note that 'field' is indeed a private member of X but that access
+// is indeed ultimately constrained by the protected inheritance from Y.
+// If someone wants to put the effort into improving this diagnostic,
+// they can feel free; even explaining it in person would be a pain.
+namespace test4 {
+ class Z;
+ class X {
+ public:
+ void f(Z *p);
+
+ private:
+ int field; // expected-note {{member is declared here}}
+ };
+
+ class Y : public X { };
+ class Z : protected Y { }; // expected-note 2 {{constrained by protected inheritance here}}
+
+ void X::f(Z *p) {
+ p->field = 0; // expected-error {{cannot cast 'test4::Z' to its protected base class 'test4::X'}} expected-error {{'field' is a private member of 'test4::X'}}
+ }
+}
+
// TODO: flesh out these cases
diff --git a/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
index e4d5fd5..ea9d2ce 100644
--- a/test/CXX/class.access/class.friend/p3-cxx0x.cpp
+++ b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
@@ -28,14 +28,19 @@ X1<Y2> x1a;
X1<Y3> x1b;
X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}}
+template<typename T> class B;
+
template<typename T>
class A {
T x;
public:
class foo {};
static int y;
+ template <typename S> friend class B<S>::ty;
};
+template <typename T> class B { typedef int ty; };
+
struct {
// Ill-formed
int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
@@ -53,3 +58,5 @@ struct {
float;
template<typename T> friend class A<T>::foo;
} a;
+
+void testA() { (void)sizeof(A<int>); }
diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp
index 132ff61..825447e 100644
--- a/test/CXX/class.access/class.protected/p1.cpp
+++ b/test/CXX/class.access/class.protected/p1.cpp
@@ -329,7 +329,7 @@ namespace test8 {
namespace test9 {
class A { // expected-note {{member is declared here}}
- protected: int foo(); // expected-note 4 {{declared}} expected-note 2 {{can only access this member on an object of type}} expected-note {{member is declared here}}
+ protected: int foo(); // expected-note 4 {{declared}} expected-note 3 {{can only access this member on an object of type}} expected-note 2 {{member is declared here}}
};
class B : public A { // expected-note {{member is declared here}}
@@ -344,14 +344,15 @@ namespace test9 {
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.B::foo(); // expected-error {{'foo' is a protected member}}
a.C::foo(); // expected-error {{'foo' is a protected member}}
+ a.D::foo(); // expected-error {{'foo' is a protected member}}
}
static void test(B &b) {
b.foo();
b.A::foo();
- b.B::foo();
+ b.B::foo(); // accessible as named in A
b.C::foo(); // expected-error {{'foo' is a protected member}}
}
OpenPOWER on IntegriCloud