Implement access checking for protected base classes.

llvm-svn: 67887
This commit is contained in:
Anders Carlsson 2009-03-28 01:09:05 +00:00
parent 2b9e7efccd
commit 0cb4cc106c
3 changed files with 49 additions and 5 deletions

View File

@ -55,7 +55,7 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
const CXXBaseSpecifier *InacessibleBase = 0;
const CXXRecordDecl* CurrentClassDecl = 0;
CXXRecordDecl* CurrentClassDecl = 0;
if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(getCurFunctionDecl()))
CurrentClassDecl = MD->getParent();
@ -79,9 +79,21 @@ bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
if (CurrentClassDecl != Element->Class)
FoundInaccessibleBase = true;
break;
case AS_protected:
// FIXME: Implement
break;
case AS_protected:
// FIXME: Check if the current function/class is a friend.
if (!CurrentClassDecl) {
FoundInaccessibleBase = true;
break;
}
if (CurrentClassDecl != Element->Class) {
QualType CurrentClassType = Context.getTypeDeclType(CurrentClassDecl);
QualType ClassType = Context.getTypeDeclType(Element->Class);
if (!IsDerivedFrom(CurrentClassType, ClassType))
FoundInaccessibleBase = true;
break;
}
}
if (FoundInaccessibleBase) {

View File

@ -40,7 +40,7 @@ namespace clang {
const CXXBaseSpecifier *Base;
/// Class - The record decl of the class that the base is a base of.
const CXXRecordDecl *Class;
CXXRecordDecl *Class;
/// SubobjectNumber - Identifies which base class subobject (of type
/// @c Base->getType()) this base path element refers to. This

View File

@ -80,3 +80,35 @@ namespace T6 {
A *a = c;
}
}
namespace T7 {
class C;
class A { };
class B : protected A { // expected-note {{'protected' inheritance specifier here}}
void f(C *);
};
class C : protected B { // expected-note {{'protected' inheritance specifier here}}
void f(C *c) {
A* a = c;
}
};
void B::f(C *c) {
A *a = c; // expected-error {{conversion from 'class T7::C' to inaccessible base class 'class T7::A'}} \
expected-error {{incompatible type initializing 'class T7::C *', expected 'class T7::A *'}}
}
class D : private C {
void f(D *d) {
A *a = d;
}
};
void f(B* b) {
A *a = b; // expected-error {{conversion from 'class T7::B' to inaccessible base class 'class T7::A'}} \
expected-error {{incompatible type initializing 'class T7::B *', expected 'class T7::A *'}}
}
}