diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2013-03-28 23:39:11 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-03-28 23:39:11 +0000 |
commit | 99a72d2d875321b4d91e6aef4e20b289f3d05db4 (patch) | |
tree | cd9a388a4f2207bbcfb2b43eac4257c02a23c7ff /lib/Sema/SemaExpr.cpp | |
parent | 123243cfd80f790a27edd1b829cd190a85f6c006 (diff) |
Objective-C: Produce precise diagnostic when
'isa' ivar is accessed provided it is the first
ivar. Fixit hint will follow in another patch.
This is continuation of // rdar://13503456
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178313 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 238d833c38..c6882908c2 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -450,6 +450,34 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) { } } +static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, + bool IsAssign) { + const ObjCIvarDecl *IV = OIRE->getDecl(); + if (!IV) + return; + + DeclarationName MemberName = IV->getDeclName(); + IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); + if (!Member || !Member->isStr("isa")) + return; + + const Expr *Base = OIRE->getBase(); + QualType BaseType = Base->getType(); + if (OIRE->isArrow()) + BaseType = BaseType->getPointeeType(); + if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) + if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) { + ObjCInterfaceDecl *ClassDeclared = 0; + ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared); + if (!ClassDeclared->getSuperClass() + && (*ClassDeclared->ivar_begin()) == IV) { + S.Diag(OIRE->getLocation(), IsAssign ? diag::warn_objc_isa_assign + : diag::warn_objc_isa_use); + S.Diag(IV->getLocation(), diag::note_ivar_decl); + } + } +} + ExprResult Sema::DefaultLvalueConversion(Expr *E) { // Handle any placeholder expressions which made it here. if (E->getType()->isPlaceholderType()) { @@ -503,7 +531,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { else Diag(E->getExprLoc(), diag::warn_objc_isa_use); } - + else if (const ObjCIvarRefExpr *OIRE = + dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts())) + DiagnoseDirectIsaAccess(*this, OIRE, false); + // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the // cv-unqualified version of T. Otherwise, the type of the @@ -8561,7 +8592,10 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, else Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign); } - + else if (const ObjCIvarRefExpr *OIRE = + dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts())) + DiagnoseDirectIsaAccess(*this, OIRE, true); + if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc, ResultTy, VK, OK, OpLoc, |