1*67e74705SXin Li// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsyntax-only -verify %s 2*67e74705SXin Li 3*67e74705SXin Li//====------------------------------------------------------------====// 4*67e74705SXin Li// Test deprecated direct usage of the 'isa' pointer. 5*67e74705SXin Li//====------------------------------------------------------------====// 6*67e74705SXin Li 7*67e74705SXin Litypedef unsigned long NSUInteger; 8*67e74705SXin Li 9*67e74705SXin Litypedef struct objc_object { 10*67e74705SXin Li struct objc_class *isa; 11*67e74705SXin Li} *id; 12*67e74705SXin Li 13*67e74705SXin Li@interface NSObject { 14*67e74705SXin Li id firstobj; 15*67e74705SXin Li struct objc_class *isa; 16*67e74705SXin Li} 17*67e74705SXin Li- (id)performSelector:(SEL)aSelector;; 18*67e74705SXin Li@end 19*67e74705SXin Li@interface Whatever : NSObject 20*67e74705SXin Li+self; 21*67e74705SXin Li-(id)foo; 22*67e74705SXin Li@end 23*67e74705SXin Li 24*67e74705SXin Listatic void func() { 25*67e74705SXin Li 26*67e74705SXin Li id x; 27*67e74705SXin Li 28*67e74705SXin Li // rdar://8290002 29*67e74705SXin Li [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 30*67e74705SXin Li [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 31*67e74705SXin Li 32*67e74705SXin Li Whatever *y; 33*67e74705SXin Li 34*67e74705SXin Li // GCC allows this, with the following warning: 35*67e74705SXin Li // instance variable 'isa' is @protected; this will be a hard error in the future 36*67e74705SXin Li // 37*67e74705SXin Li // FIXME: see if we can avoid the warning that follows the error. 38*67e74705SXin Li [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \ 39*67e74705SXin Li expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} 40*67e74705SXin Li [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \ 41*67e74705SXin Li expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} 42*67e74705SXin Li} 43*67e74705SXin Li 44*67e74705SXin Li// rdar://11702488 45*67e74705SXin Li// If an ivar is (1) the first ivar in a root class and (2) named `isa`, 46*67e74705SXin Li// then it should get the same warnings that id->isa gets. 47*67e74705SXin Li 48*67e74705SXin Li@interface BaseClass { 49*67e74705SXin Li@public 50*67e74705SXin Li Class isa; // expected-note 4 {{instance variable is declared here}} 51*67e74705SXin Li} 52*67e74705SXin Li@end 53*67e74705SXin Li 54*67e74705SXin Li@interface OtherClass { 55*67e74705SXin Li@public 56*67e74705SXin Li id firstIvar; 57*67e74705SXin Li Class isa; // note, not first ivar; 58*67e74705SXin Li} 59*67e74705SXin Li@end 60*67e74705SXin Li 61*67e74705SXin Li@interface Subclass : BaseClass @end 62*67e74705SXin Li 63*67e74705SXin Li@interface SiblingClass : BaseClass @end 64*67e74705SXin Li 65*67e74705SXin Li@interface Root @end 66*67e74705SXin Li 67*67e74705SXin Li@interface hasIsa : Root { 68*67e74705SXin Li@public 69*67e74705SXin Li Class isa; // note, isa is not in root class 70*67e74705SXin Li} 71*67e74705SXin Li@end 72*67e74705SXin Li 73*67e74705SXin Li@implementation Subclass 74*67e74705SXin Li-(void)method { 75*67e74705SXin Li hasIsa *u; 76*67e74705SXin Li id v; 77*67e74705SXin Li BaseClass *w; 78*67e74705SXin Li Subclass *x; 79*67e74705SXin Li SiblingClass *y; 80*67e74705SXin Li OtherClass *z; 81*67e74705SXin Li (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 82*67e74705SXin Li (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 83*67e74705SXin Li (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 84*67e74705SXin Li (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} 85*67e74705SXin Li (void)z->isa; 86*67e74705SXin Li (void)u->isa; 87*67e74705SXin Li 88*67e74705SXin Li w->isa = 0; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}} 89*67e74705SXin Li} 90*67e74705SXin Li@end 91*67e74705SXin Li 92*67e74705SXin Li// Test for introspection of Objective-C pointers via bitmasking. 93*67e74705SXin Li 94*67e74705SXin Livoid testBitmasking(NSObject *p) { 95*67e74705SXin Li (void) (((NSUInteger) p) & 0x1); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} 96*67e74705SXin Li (void) (0x1 & ((NSUInteger) p)); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} 97*67e74705SXin Li (void) (((NSUInteger) p) ^ 0x1); // no-warning 98*67e74705SXin Li (void) (0x1 ^ ((NSUInteger) p)); // no-warning 99*67e74705SXin Li (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} 100*67e74705SXin Li#pragma clang diagnostic push 101*67e74705SXin Li#pragma clang diagnostic ignored "-Wdeprecated-objc-pointer-introspection-performSelector" 102*67e74705SXin Li (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // no-warning 103*67e74705SXin Li#pragma clang diagnostic pop 104*67e74705SXin Li}