xref: /aosp_15_r20/external/clang/test/Analysis/inlining/RetainCountExamples.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
2*67e74705SXin Li
3*67e74705SXin Litypedef signed char BOOL;
4*67e74705SXin Litypedef struct objc_class *Class;
5*67e74705SXin Litypedef struct objc_object {
6*67e74705SXin Li    Class isa;
7*67e74705SXin Li} *id;
8*67e74705SXin Li@protocol NSObject  - (BOOL)isEqual:(id)object; @end
9*67e74705SXin Li@interface NSObject <NSObject> {}
10*67e74705SXin Li+(id)alloc;
11*67e74705SXin Li+(id)new;
12*67e74705SXin Li- (oneway void)release;
13*67e74705SXin Li-(id)init;
14*67e74705SXin Li-(id)autorelease;
15*67e74705SXin Li-(id)copy;
16*67e74705SXin Li- (Class)class;
17*67e74705SXin Li-(id)retain;
18*67e74705SXin Li- (oneway void)release;
19*67e74705SXin Li@end
20*67e74705SXin Li
21*67e74705SXin Li@interface SelfStaysLive : NSObject
22*67e74705SXin Li- (id)init;
23*67e74705SXin Li@end
24*67e74705SXin Li
25*67e74705SXin Li@implementation SelfStaysLive
26*67e74705SXin Li- (id)init {
27*67e74705SXin Li  return [super init];
28*67e74705SXin Li}
29*67e74705SXin Li@end
30*67e74705SXin Li
31*67e74705SXin Livoid selfStaysLive() {
32*67e74705SXin Li    SelfStaysLive *foo = [[SelfStaysLive alloc] init];
33*67e74705SXin Li    [foo release];
34*67e74705SXin Li}
35*67e74705SXin Li
36*67e74705SXin Li// Test that retain release checker warns on leaks and use-after-frees when
37*67e74705SXin Li// self init is not enabled.
38*67e74705SXin Li// radar://12115830
39*67e74705SXin Li@interface ParentOfCell : NSObject
40*67e74705SXin Li- (id)initWithInt: (int)inInt;
41*67e74705SXin Li@end
42*67e74705SXin Li@interface Cell : ParentOfCell{
43*67e74705SXin Li  int x;
44*67e74705SXin Li}
45*67e74705SXin Li- (id)initWithInt: (int)inInt;
46*67e74705SXin Li+ (void)testOverRelease;
47*67e74705SXin Li+ (void)testLeak;
48*67e74705SXin Li@property int x;
49*67e74705SXin Li@end
50*67e74705SXin Li@implementation Cell
51*67e74705SXin Li@synthesize x;
52*67e74705SXin Li- (id) initWithInt: (int)inInt {
53*67e74705SXin Li  [super initWithInt: inInt];
54*67e74705SXin Li  self.x = inInt; // no-warning
55*67e74705SXin Li  return self; // Self Init checker would produce a warning here.
56*67e74705SXin Li}
57*67e74705SXin Li+ (void) testOverRelease {
58*67e74705SXin Li  Cell *sharedCell3 = [[Cell alloc] initWithInt: 3];
59*67e74705SXin Li  [sharedCell3 release];
60*67e74705SXin Li  [sharedCell3 release]; // expected-warning {{Reference-counted object is used after it is released}}
61*67e74705SXin Li}
62*67e74705SXin Li+ (void) testLeak {
63*67e74705SXin Li  Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}}
64*67e74705SXin Li}
65*67e74705SXin Li@end
66*67e74705SXin Li
67*67e74705SXin Li// We should stop tracking some objects even when we inline the call.
68*67e74705SXin Li// Specialically, the objects passed into calls with delegate and callback
69*67e74705SXin Li// parameters.
70*67e74705SXin Li@class DelegateTest;
71*67e74705SXin Litypedef void (*ReleaseCallbackTy) (DelegateTest *c);
72*67e74705SXin Li
73*67e74705SXin Li@interface Delegate : NSObject
74*67e74705SXin Li@end
75*67e74705SXin Li
76*67e74705SXin Li@interface DelegateTest : NSObject {
77*67e74705SXin Li  Delegate *myDel;
78*67e74705SXin Li}
79*67e74705SXin Li// Object initialized with a delagate which could potentially release it.
80*67e74705SXin Li- (id)initWithDelegate: (id) d;
81*67e74705SXin Li
82*67e74705SXin Li- (void) setDelegate: (id) d;
83*67e74705SXin Li
84*67e74705SXin Li// Releases object through callback.
85*67e74705SXin Li+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc;
86*67e74705SXin Li
87*67e74705SXin Li+ (void)test: (Delegate *)d;
88*67e74705SXin Li
89*67e74705SXin Li@property (assign) Delegate* myDel;
90*67e74705SXin Li@end
91*67e74705SXin Li
92*67e74705SXin Livoid releaseObj(DelegateTest *c);
93*67e74705SXin Li
94*67e74705SXin Li// Releases object through callback.
95*67e74705SXin Livoid updateObject(DelegateTest *c, ReleaseCallbackTy rel) {
96*67e74705SXin Li  rel(c);
97*67e74705SXin Li}
98*67e74705SXin Li
99*67e74705SXin Li@implementation DelegateTest
100*67e74705SXin Li@synthesize myDel;
101*67e74705SXin Li
102*67e74705SXin Li- (id) initWithDelegate: (id) d {
103*67e74705SXin Li    if ((self = [super init]))
104*67e74705SXin Li      myDel = d;
105*67e74705SXin Li    return self;
106*67e74705SXin Li}
107*67e74705SXin Li
108*67e74705SXin Li- (void) setDelegate: (id) d {
109*67e74705SXin Li    myDel = d;
110*67e74705SXin Li}
111*67e74705SXin Li
112*67e74705SXin Li+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc {
113*67e74705SXin Li  rc(obj);
114*67e74705SXin Li}
115*67e74705SXin Li
116*67e74705SXin Li+ (void) test: (Delegate *)d {
117*67e74705SXin Li  DelegateTest *obj1 = [[DelegateTest alloc] initWithDelegate: d]; // no-warning
118*67e74705SXin Li  DelegateTest *obj2 = [[DelegateTest alloc] init]; // no-warning
119*67e74705SXin Li  DelegateTest *obj3 = [[DelegateTest alloc] init]; // no-warning
120*67e74705SXin Li  updateObject(obj2, releaseObj);
121*67e74705SXin Li  [DelegateTest updateObject: obj3
122*67e74705SXin Li        WithCallback: releaseObj];
123*67e74705SXin Li  DelegateTest *obj4 = [[DelegateTest alloc] init]; // no-warning
124*67e74705SXin Li  [obj4 setDelegate: d];
125*67e74705SXin Li}
126*67e74705SXin Li@end
127*67e74705SXin Li
128