diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2013-04-02 18:57:54 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-04-02 18:57:54 +0000 |
commit | 0c70181854a95fca0e0d56dfa1203eb2216052ea (patch) | |
tree | 2cad17730b0374e71b23691e5044db3d5e55f8ce /lib/Sema/SemaExpr.cpp | |
parent | 1b461b0ad072fd36c8c20e7bd29448f08050a3c3 (diff) |
Objective-C: Provide fixit hints when warning
about 'isa' ivar being explicitely accessed
when base is a user class object reference.
// rdar://13503456
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178562 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c1d86550a5..5459d74016 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -456,7 +456,8 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) { } static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, - bool IsAssign) { + SourceLocation AssignLoc, + const Expr* RHS) { const ObjCIvarDecl *IV = OIRE->getDecl(); if (!IV) return; @@ -476,8 +477,35 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, 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); + if (RHS) { + NamedDecl *ObjectSetClass = + S.LookupSingleName(S.TUScope, + &S.Context.Idents.get("object_setClass"), + SourceLocation(), S.LookupOrdinaryName); + if (ObjectSetClass) { + SourceLocation RHSLocEnd = S.PP.getLocForEndOfToken(RHS->getLocEnd()); + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) << + FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") << + FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(), + AssignLoc), ",") << + FixItHint::CreateInsertion(RHSLocEnd, ")"); + } + else + S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign); + } else { + NamedDecl *ObjectGetClass = + S.LookupSingleName(S.TUScope, + &S.Context.Idents.get("object_getClass"), + SourceLocation(), S.LookupOrdinaryName); + if (ObjectGetClass) + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) << + FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") << + FixItHint::CreateReplacement( + SourceRange(OIRE->getOpLoc(), + OIRE->getLocEnd()), ")"); + else + S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use); + } S.Diag(IV->getLocation(), diag::note_ivar_decl); } } @@ -538,7 +566,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { } else if (const ObjCIvarRefExpr *OIRE = dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts())) - DiagnoseDirectIsaAccess(*this, OIRE, false); + DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/0); // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the @@ -2104,7 +2132,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(), - Loc, + Loc, IV->getLocation(), SelfExpr.take(), true, true); @@ -8628,7 +8656,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, } else if (const ObjCIvarRefExpr *OIRE = dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts())) - DiagnoseDirectIsaAccess(*this, OIRE, true); + DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get()); if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc, |