diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-03-02 21:55:29 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-03-02 21:55:29 +0000 |
commit | 077c1e7377edeef3438ba59cd8151177868b62d4 (patch) | |
tree | 4985351aff694e6708fdc5d2b1344ab7365c30bf /lib | |
parent | ae3487f78747512ce718c6c00ef888787da50a1e (diff) |
Diagnose a variety of access of ivars when they conflict with
local or global variables in instance/class methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65879 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index aca19cdca6..32ef0f7b35 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -627,27 +627,42 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (II && getCurMethodDecl()) { // There are two cases to handle here. 1) scoped lookup could have failed, // in which case we should look for an ivar. 2) scoped lookup could have - // found a decl, but that decl is outside the current method (i.e. a global - // variable). In these two cases, we do a lookup for an ivar with this - // name, if the lookup suceeds, we replace it our current decl. + // found a decl, but that decl is outside the current instance method (i.e. + // a global variable). In these two cases, we do a lookup for an ivar with + // this name, if the lookup sucedes, we replace it our current decl. if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) { ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface(); if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) { // Check if referencing a field with __attribute__((deprecated)). if (DiagnoseUseOfDecl(IV, Loc)) return ExprError(); - - // FIXME: This should use a new expr for a direct reference, don't turn - // this into Self->ivar, just return a BareIVarExpr or something. - IdentifierInfo &II = Context.Idents.get("self"); - OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); - ObjCIvarRefExpr *MRef = new (Context) ObjCIvarRefExpr(IV, IV->getType(), - Loc, static_cast<Expr*>(SelfExpr.release()), - true, true); - Context.setFieldDecl(IFace, IV, MRef); - return Owned(MRef); + bool IsClsMethod = getCurMethodDecl()->isClassMethod(); + // If a class method attemps to use a free standing ivar, this is + // an error. + if (IsClsMethod && D && !D->isDefinedOutsideFunctionOrMethod()) + return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method) + << IV->getDeclName()); + // If a class method uses a global variable, even if an ivar with + // same name exists, use the global. + if (!IsClsMethod) { + // FIXME: This should use a new expr for a direct reference, don't turn + // this into Self->ivar, just return a BareIVarExpr or something. + IdentifierInfo &II = Context.Idents.get("self"); + OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); + ObjCIvarRefExpr *MRef = new (Context) ObjCIvarRefExpr(IV, IV->getType(), + Loc, static_cast<Expr*>(SelfExpr.release()), + true, true); + Context.setFieldDecl(IFace, IV, MRef); + return Owned(MRef); + } } } + else if (getCurMethodDecl()->isInstanceMethod()) { + // We should warn if a local variable hides an ivar. + ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface(); + if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) + Diag(Loc, diag::warn_ivar_use_hidden)<<IV->getDeclName(); + } // Needed to implement property "super.method" notation. if (D == 0 && II->isStr("super")) { QualType T = Context.getPointerType(Context.getObjCInterfaceType( |