forked from OSchip/llvm-project
Access checking for overloaded operators.
llvm-svn: 94725
This commit is contained in:
parent
81310810bd
commit
b3a4400554
|
@ -2431,6 +2431,8 @@ public:
|
|||
bool CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
|
||||
NamedDecl *D,
|
||||
AccessSpecifier Access);
|
||||
bool CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
|
||||
NamedDecl *D, AccessSpecifier Access);
|
||||
bool CheckAccess(const LookupResult &R, NamedDecl *D, AccessSpecifier Access);
|
||||
void CheckAccess(const LookupResult &R);
|
||||
|
||||
|
|
|
@ -306,6 +306,30 @@ bool Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Checks access to an overloaded member operator.
|
||||
bool Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
|
||||
Expr *ObjectExpr,
|
||||
NamedDecl *MemberOperator,
|
||||
AccessSpecifier Access) {
|
||||
if (!getLangOptions().AccessControl)
|
||||
return false;
|
||||
|
||||
const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
|
||||
assert(RT && "found member operator but object expr not of record type");
|
||||
CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
|
||||
|
||||
LookupResult R(*this, DeclarationName(), OpLoc, LookupOrdinaryName);
|
||||
R.suppressDiagnostics();
|
||||
|
||||
R.setNamingClass(NamingClass);
|
||||
if (CheckAccess(R, MemberOperator, Access))
|
||||
return true;
|
||||
|
||||
// FIXME: protected check
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Checks access to all the declarations in the given result set.
|
||||
void Sema::CheckAccess(const LookupResult &R) {
|
||||
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
|
||||
|
|
|
@ -5515,10 +5515,10 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
// FIXME: access control
|
||||
|
||||
// Convert the arguments.
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
|
||||
CheckMemberOperatorAccess(OpLoc, Args[0], Method, Best->getAccess());
|
||||
|
||||
if (PerformObjectArgumentInitialization(Input, Method))
|
||||
return ExprError();
|
||||
} else {
|
||||
|
@ -5698,10 +5698,11 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
// FIXME: access control
|
||||
|
||||
// Convert the arguments.
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
|
||||
// Best->Access is only meaningful for class members.
|
||||
CheckMemberOperatorAccess(OpLoc, Args[0], Method, Best->getAccess());
|
||||
|
||||
OwningExprResult Arg1
|
||||
= PerformCopyInitialization(
|
||||
InitializedEntity::InitializeParameter(
|
||||
|
@ -5873,7 +5874,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
|
|||
// We matched an overloaded operator. Build a call to that
|
||||
// operator.
|
||||
|
||||
// FIXME: access control
|
||||
CheckMemberOperatorAccess(LLoc, Args[0], FnDecl, Best->getAccess());
|
||||
|
||||
// Convert the arguments.
|
||||
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
|
||||
|
|
|
@ -31,3 +31,39 @@ namespace test0 {
|
|||
void (A::*c)(Private&) = &A::foo; // expected-error {{access to private member outside any class}}
|
||||
}
|
||||
}
|
||||
|
||||
// Member operators.
|
||||
namespace test1 {
|
||||
class A {
|
||||
public:
|
||||
void operator+(Public&);
|
||||
void operator[](Public&);
|
||||
protected:
|
||||
void operator+(Protected&); // expected-note {{declared protected here}}
|
||||
void operator[](Protected&); // expected-note {{declared protected here}}
|
||||
private:
|
||||
void operator+(Private&); // expected-note {{declared private here}}
|
||||
void operator[](Private&); // expected-note {{declared private here}}
|
||||
void operator-(); // 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 {{access to protected member}}
|
||||
a + priv; // expected-error {{access to private member}}
|
||||
a[pub];
|
||||
a[prot]; // expected-error {{access to protected member}}
|
||||
a[priv]; // expected-error {{access to private member}}
|
||||
-a; // expected-error {{access to private member}}
|
||||
|
||||
const A &ca = a;
|
||||
ca + pub;
|
||||
ca + prot;
|
||||
ca + priv;
|
||||
-ca;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue