summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-03-28 23:39:11 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-03-28 23:39:11 +0000
commit3b602ce5a4a1fc3ace06aa794c78466947012f9c (patch)
tree33b7f1c36928f092dd0ff3f050cf0f1f7f94c074 /clang/lib/Sema
parent5fff5c7b2679da199bd566cd80c5d058c7fc3d86 (diff)
downloadbcm5719-llvm-3b602ce5a4a1fc3ace06aa794c78466947012f9c.tar.gz
bcm5719-llvm-3b602ce5a4a1fc3ace06aa794c78466947012f9c.zip
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 llvm-svn: 178313
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp38
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp13
2 files changed, 36 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 238d833c389..c6882908c24 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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,
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 481c22135e9..54190edf37d 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1139,19 +1139,6 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
ObjCImpDecl, HasTemplateArgs);
goto fail;
}
- else if (Member && Member->isStr("isa")) {
- // If an ivar is (1) the first ivar in a root class and (2) named `isa`,
- // then issue the same deprecated warning that id->isa gets.
- ObjCInterfaceDecl *ClassDeclared = 0;
- if (ObjCIvarDecl *IV =
- IDecl->lookupInstanceVariable(Member, ClassDeclared)) {
- if (!ClassDeclared->getSuperClass()
- && (*ClassDeclared->ivar_begin()) == IV) {
- Diag(MemberLoc, diag::warn_objc_isa_use);
- Diag(IV->getLocation(), diag::note_ivar_decl);
- }
- }
- }
if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
BaseExpr.get()))
OpenPOWER on IntegriCloud