xref: /aosp_15_r20/external/clang/test/SemaObjC/deprecated-objc-introspection.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
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}