102 lines · plain
1// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsyntax-only -verify %s2 3//====------------------------------------------------------------====//4// Test deprecated direct usage of the 'isa' pointer.5//====------------------------------------------------------------====//6 7typedef unsigned long NSUInteger;8 9typedef struct objc_object {10 struct objc_class *isa;11} *id;12 13@interface NSObject {14 id firstobj;15 struct objc_class *isa;16}17- (id)performSelector:(SEL)aSelector;;18@end19@interface Whatever : NSObject20+self;21-(id)foo;22@end23 24static void func(void) {25 26 id x;27 28 [(*x).isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}29 [x->isa self]; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}30 31 Whatever *y;32 33 // GCC allows this, with the following warning: 34 // instance variable 'isa' is @protected; this will be a hard error in the future35 //36 // FIXME: see if we can avoid the warning that follows the error.37 [(*y).isa self]; // expected-error {{instance variable 'isa' is protected}} \38 expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}}39 [y->isa self]; // expected-error {{instance variable 'isa' is protected}} \40 expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}}41}42 43// If an ivar is (1) the first ivar in a root class and (2) named `isa`,44// then it should get the same warnings that id->isa gets.45 46@interface BaseClass {47@public48 Class isa; // expected-note 4 {{instance variable is declared here}}49}50@end51 52@interface OtherClass {53@public54 id firstIvar;55 Class isa; // note, not first ivar;56}57@end58 59@interface Subclass : BaseClass @end60 61@interface SiblingClass : BaseClass @end62 63@interface Root @end64 65@interface hasIsa : Root {66@public67 Class isa; // note, isa is not in root class68}69@end70 71@implementation Subclass72-(void)method {73 hasIsa *u;74 id v;75 BaseClass *w;76 Subclass *x;77 SiblingClass *y;78 OtherClass *z;79 (void)v->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}80 (void)w->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}81 (void)x->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}82 (void)y->isa; // expected-warning {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}83 (void)z->isa;84 (void)u->isa;85 86 w->isa = 0; // expected-warning {{assignment to Objective-C's isa is deprecated in favor of object_setClass()}}87}88@end89 90// Test for introspection of Objective-C pointers via bitmasking.91 92void testBitmasking(NSObject *p) {93 (void) (((NSUInteger) p) & 0x1); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}}94 (void) (0x1 & ((NSUInteger) p)); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}}95 (void) (((NSUInteger) p) ^ 0x1); // no-warning96 (void) (0x1 ^ ((NSUInteger) p)); // no-warning97 (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}}98#pragma clang diagnostic push99#pragma clang diagnostic ignored "-Wdeprecated-objc-pointer-introspection-performSelector"100 (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // no-warning101#pragma clang diagnostic pop102}