forked from OSchip/llvm-project
Implemented access check for ivars accessed inside
c-style functions declared inside objc @implementations. llvm-svn: 66087
This commit is contained in:
parent
19ce8619da
commit
b8d091c4eb
|
@ -517,7 +517,8 @@ namespace {
|
|||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
SourceLocation MemberLoc,
|
||||
IdentifierInfo &Member) {
|
||||
IdentifierInfo &Member,
|
||||
DeclTy *ImplDecl) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return ExprEmpty();
|
||||
}
|
||||
|
|
|
@ -642,7 +642,8 @@ public:
|
|||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
SourceLocation MemberLoc,
|
||||
IdentifierInfo &Member) {
|
||||
IdentifierInfo &Member,
|
||||
DeclTy *ObjCImpDecl) {
|
||||
return ExprEmpty();
|
||||
}
|
||||
|
||||
|
|
|
@ -852,7 +852,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
|
|||
if (!LHS.isInvalid()) {
|
||||
LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc,
|
||||
OpKind, Tok.getLocation(),
|
||||
*Tok.getIdentifierInfo());
|
||||
*Tok.getIdentifierInfo(),
|
||||
ObjCImpDecl);
|
||||
}
|
||||
ConsumeToken();
|
||||
break;
|
||||
|
|
|
@ -1082,12 +1082,15 @@ Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
|
|||
Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
|
||||
assert(Tok.isObjCAtKeyword(tok::objc_end) &&
|
||||
"ParseObjCAtEndDeclaration(): Expected @end");
|
||||
DeclTy *Result = ObjCImpDecl;
|
||||
ConsumeToken(); // the "end" identifier
|
||||
if (ObjCImpDecl)
|
||||
if (ObjCImpDecl) {
|
||||
Actions.ActOnAtEnd(atLoc, ObjCImpDecl);
|
||||
ObjCImpDecl = 0;
|
||||
}
|
||||
else
|
||||
Diag(atLoc, diag::warn_expected_implementation); // missing @implementation
|
||||
return ObjCImpDecl;
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// compatibility-alias-decl:
|
||||
|
|
|
@ -1158,7 +1158,8 @@ public:
|
|||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
SourceLocation MemberLoc,
|
||||
IdentifierInfo &Member);
|
||||
IdentifierInfo &Member,
|
||||
DeclTy *ImplDecl=0);
|
||||
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
|
||||
FunctionDecl *FDecl,
|
||||
const FunctionProtoType *Proto,
|
||||
|
|
|
@ -1666,16 +1666,11 @@ static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
|
|||
return &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]);
|
||||
}
|
||||
|
||||
ObjCImplementationDecl *getCurImplementationDecl(DeclContext *DC) {
|
||||
while (DC && !isa<ObjCImplementationDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
return dyn_cast_or_null<ObjCImplementationDecl>(DC);
|
||||
}
|
||||
|
||||
Action::OwningExprResult
|
||||
Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind, SourceLocation MemberLoc,
|
||||
IdentifierInfo &Member) {
|
||||
IdentifierInfo &Member,
|
||||
DeclTy *ObjCImpDecl) {
|
||||
Expr *BaseExpr = static_cast<Expr *>(Base.release());
|
||||
assert(BaseExpr && "no record expression");
|
||||
|
||||
|
@ -1803,17 +1798,24 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
ObjCInterfaceDecl *ClassOfMethodDecl = 0;
|
||||
if (ObjCMethodDecl *MD = getCurMethodDecl())
|
||||
ClassOfMethodDecl = MD->getClassInterface();
|
||||
else if (FunctionDecl *FD = getCurFunctionDecl()) {
|
||||
// FIXME: This isn't working yet. Will discuss with Fariborz.
|
||||
// FIXME: Should be ObjCImplDecl, so categories can work.
|
||||
// Need to fiddle with castToDeclContext/castFromDeclContext.
|
||||
ObjCImplementationDecl *ImpDecl = getCurImplementationDecl(FD);
|
||||
if (ImpDecl)
|
||||
ClassOfMethodDecl = ImpDecl->getClassInterface();
|
||||
else if (ObjCImpDecl && getCurFunctionDecl()) {
|
||||
// Case of a c-function declared inside an objc implementation.
|
||||
// FIXME: For a c-style function nested inside an objc implementation
|
||||
// class, there is no implementation context available, so we pass down
|
||||
// the context as argument to this routine. Ideally, this context need
|
||||
// be passed down in the AST node and somehow calculated from the AST
|
||||
// for a function decl.
|
||||
Decl *ImplDecl = static_cast<Decl *>(ObjCImpDecl);
|
||||
if (ObjCImplementationDecl *IMPD =
|
||||
dyn_cast<ObjCImplementationDecl>(ImplDecl))
|
||||
ClassOfMethodDecl = IMPD->getClassInterface();
|
||||
else if (ObjCCategoryImplDecl* CatImplClass =
|
||||
dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
|
||||
ClassOfMethodDecl = CatImplClass->getClassInterface();
|
||||
}
|
||||
if (IV->getAccessControl() == ObjCIvarDecl::Private) {
|
||||
if (IV->getAccessControl() == ObjCIvarDecl::Private) {
|
||||
if (ClassDeclared != IFTy->getDecl() ||
|
||||
(ClassOfMethodDecl && (ClassOfMethodDecl != ClassDeclared)))
|
||||
ClassOfMethodDecl != ClassDeclared)
|
||||
Diag(MemberLoc, diag::error_private_ivar_access) << IV->getDeclName();
|
||||
}
|
||||
// @protected
|
||||
|
|
|
@ -73,7 +73,7 @@ int main (void)
|
|||
{
|
||||
MySuperClass *s = 0;
|
||||
int access;
|
||||
access = s->private; // FIXME: {{instance variable 'private' is private}}
|
||||
access = s->private; // expected-error {{instance variable 'private' is private}}
|
||||
access = s->protected; // expected-error {{instance variable 'protected' is protected}}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue