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