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