Access control for implicit destructor calls. Diagnostic could be orders of

magnitude clearer.

llvm-svn: 95078
This commit is contained in:
John McCall 2010-02-02 08:45:54 +00:00
parent 49786a6c31
commit 6781b05a92
5 changed files with 63 additions and 4 deletions

View File

@ -2417,6 +2417,7 @@ public:
AccessSpecifier Access);
bool CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D,
AccessSpecifier Access);
bool CheckDestructorAccess(SourceLocation Loc, QualType T);
bool CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
NamedDecl *D, AccessSpecifier Access);
bool CheckAccess(const LookupResult &R, NamedDecl *D, AccessSpecifier Access);

View File

@ -306,6 +306,31 @@ bool Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
return false;
}
bool Sema::CheckDestructorAccess(SourceLocation Loc,
QualType T) {
if (!getLangOptions().AccessControl)
return false;
const RecordType *Record = T->getAs<RecordType>();
if (!Record)
return false;
CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Record->getDecl());
CXXDestructorDecl *Dtor = NamingClass->getDestructor(Context);
AccessSpecifier Access = Dtor->getAccess();
if (Access == AS_public)
return false;
LookupResult R(*this, Dtor->getDeclName(), Loc, LookupOrdinaryName);
R.suppressDiagnostics();
R.setNamingClass(NamingClass);
return CheckAccess(R, Dtor, Access);
// FIXME: protected check
}
/// Checks access to a constructor.
bool Sema::CheckConstructorAccess(SourceLocation UseLoc,
CXXConstructorDecl *Constructor,

View File

@ -2637,6 +2637,9 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
}
}
if (getLangOptions().AccessControl)
CheckDestructorAccess(Param->getLocation(), Param->getType());
}
return HasInvalidParm;

View File

@ -3985,10 +3985,11 @@ bool Sema::InitializeVarWithConstructor(VarDecl *VD,
void Sema::FinalizeVarWithDestructor(VarDecl *VD, QualType DeclInitType) {
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(
DeclInitType->getAs<RecordType>()->getDecl());
if (!ClassDecl->hasTrivialDestructor())
if (CXXDestructorDecl *Destructor =
const_cast<CXXDestructorDecl*>(ClassDecl->getDestructor(Context)))
MarkDeclarationReferenced(VD->getLocation(), Destructor);
if (!ClassDecl->hasTrivialDestructor()) {
CXXDestructorDecl *Destructor = ClassDecl->getDestructor(Context);
MarkDeclarationReferenced(VD->getLocation(), Destructor);
CheckDestructorAccess(VD->getLocation(), VD->getType());
}
}
/// AddCXXDirectInitializerToDecl - This action is called immediately after

View File

@ -83,3 +83,32 @@ namespace test1 {
ca(priv); // expected-error {{access to private member}}
}
}
// Implicit constructor calls.
namespace test2 {
class A {
private:
A(); // expected-note {{declared private here}}
static A foo;
};
A a; // expected-error {{access to private member}}
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 {{access to private member}}
A A::foo;
void foo(A param) { // expected-error {{access to private member}}
A local; // expected-error {{access to private member}}
}
}