class to the declaring class in a class member access. This check does not appear to be backed by any rule in the standard (the rule in question was likely removed over the years), and only ever produces duplicate diagnostics. (It's also not meaningful because there isn't a unique declaring class after the resolution of core issue 39.)
99 lines
2.3 KiB
C++
99 lines
2.3 KiB
C++
// RUN: %clang_cc1 -verify %s
|
|
|
|
namespace test0 {
|
|
struct A {
|
|
static int x;
|
|
};
|
|
struct B : A {};
|
|
struct C : B {};
|
|
|
|
int test() {
|
|
return A::x
|
|
+ B::x
|
|
+ C::x;
|
|
}
|
|
}
|
|
|
|
namespace test1 {
|
|
struct A {
|
|
private: static int x; // expected-note 5 {{declared private here}}
|
|
static int test() { return x; }
|
|
};
|
|
struct B : public A {
|
|
static int test() { return x; } // expected-error {{private member}}
|
|
};
|
|
struct C : private A {
|
|
static int test() { return x; } // expected-error {{private member}}
|
|
};
|
|
|
|
struct D {
|
|
public: static int x; // expected-note{{member is declared here}}
|
|
static int test() { return x; }
|
|
};
|
|
struct E : private D { // expected-note{{constrained by private inheritance}}
|
|
static int test() { return x; }
|
|
};
|
|
|
|
int test() {
|
|
return A::x // expected-error {{private member}}
|
|
+ B::x // expected-error {{private member}}
|
|
+ C::x // expected-error {{private member}}
|
|
+ D::x
|
|
+ E::x; // expected-error {{private member}}
|
|
}
|
|
}
|
|
|
|
namespace test2 {
|
|
class A {
|
|
protected: static int x; // expected-note{{member is declared here}}
|
|
};
|
|
|
|
class B : private A {}; // expected-note {{private inheritance}}
|
|
class C : private A {
|
|
int test(B *b) {
|
|
return b->x; // expected-error {{private member}}
|
|
}
|
|
};
|
|
}
|
|
|
|
namespace test3 {
|
|
class A {
|
|
protected: static int x;
|
|
};
|
|
|
|
class B : public A {};
|
|
class C : private A {
|
|
int test(B *b) {
|
|
// x is accessible at C when named in A.
|
|
// A is an accessible base of B at C.
|
|
// Therefore this succeeds.
|
|
return b->x;
|
|
}
|
|
};
|
|
}
|
|
|
|
// 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 {{constrained by protected inheritance here}}
|
|
|
|
void X::f(Z *p) {
|
|
p->field = 0; // expected-error {{'field' is a private member of 'test4::X'}}
|
|
}
|
|
}
|
|
|
|
// TODO: flesh out these cases
|