diff options
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, |