objective-c: If an ivar is (1) the first ivar in a root class and (2) named `isa`,

then it should get the same warnings that id->isa gets. // rdar://11702488

llvm-svn: 158938
This commit is contained in:
Fariborz Jahanian 2012-06-21 21:35:15 +00:00
parent dc6085e52d
commit 25cb4acdc2
2 changed files with 62 additions and 1 deletions

View File

@ -1149,7 +1149,20 @@ 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()))
return ExprError();

View File

@ -5,6 +5,7 @@ typedef struct objc_object {
} *id;
@interface NSObject {
id firstobj;
struct objc_class *isa;
}
@end
@ -33,3 +34,50 @@ static void func() {
expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \
expected-warning{{method '-self' not found (return type defaults to 'id')}}
}
// rdar://11702488
// If an ivar is (1) the first ivar in a root class and (2) named `isa`,
// then it should get the same warnings that id->isa gets.
@interface BaseClass {
@public
Class isa; // expected-note 3 {{ivar is declared here}}
}
@end
@interface OtherClass {
@public
id firstIvar;
Class isa; // note, not first ivar;
}
@end
@interface Subclass : BaseClass @end
@interface SiblingClass : BaseClass @end
@interface Root @end
@interface hasIsa : Root {
@public
Class isa; // note, isa is not in root class
}
@end
@implementation Subclass
-(void)method {
hasIsa *u;
id v;
BaseClass *w;
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)z->isa;
(void)u->isa;
}
@end