forked from OSchip/llvm-project
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
This commit is contained in:
parent
5fff5c7b26
commit
3b602ce5a4
|
@ -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,
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -39,7 +39,7 @@ static void func() {
|
|||
|
||||
@interface BaseClass {
|
||||
@public
|
||||
Class isa; // expected-note 3 {{instance variable is declared here}}
|
||||
Class isa; // expected-note 4 {{instance variable is declared here}}
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -70,12 +70,14 @@ static void func() {
|
|||
Subclass *x;
|
||||
SiblingClass *y;
|
||||
OtherClass *z;
|
||||
(void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
|
||||
(void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
|
||||
(void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
|
||||
(void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated}}
|
||||
(void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
|
||||
(void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
|
||||
(void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
|
||||
(void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
|
||||
(void)z->isa;
|
||||
(void)u->isa;
|
||||
|
||||
w->isa = 0; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}}
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in New Issue