xref: /aosp_15_r20/external/clang/test/Analysis/inlining/retain-count-self-init.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -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@end
19*67e74705SXin Li
20*67e74705SXin Li// We do not want to overhelm user with error messages in case they forgot to
21*67e74705SXin Li// assign to self and check that the result of [super init] is non-nil. So
22*67e74705SXin Li// stop tracking the receiver of init with respect to Retain Release checker.
23*67e74705SXin Li// radar://12115830
24*67e74705SXin Li@interface ParentOfCell : NSObject
25*67e74705SXin Li- (id)initWithInt: (int)inInt;
26*67e74705SXin Li@end
27*67e74705SXin Li@interface Cell : ParentOfCell{
28*67e74705SXin Li  int x;
29*67e74705SXin Li}
30*67e74705SXin Li- (id)init;
31*67e74705SXin Li+ (void)test;
32*67e74705SXin Li@property int x;
33*67e74705SXin Li@end
34*67e74705SXin Li@implementation Cell
35*67e74705SXin Li@synthesize x;
36*67e74705SXin Li- (id) init {
37*67e74705SXin Li  [super init];
38*67e74705SXin Li  self.x = 3; // no-warning
39*67e74705SXin Li  return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self)}}
40*67e74705SXin Li}
41*67e74705SXin Li- (id) initWithInt: (int)inInt {
42*67e74705SXin Li  [super initWithInt: inInt];
43*67e74705SXin Li  self.x = inInt; // no-warning
44*67e74705SXin Li  return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self)}}
45*67e74705SXin Li}
46*67e74705SXin Li- (id) init2 {
47*67e74705SXin Li  [self init]; // The call [self init] is inlined. We will warn inside the inlined body.
48*67e74705SXin Li  self.x = 2; // no-warning
49*67e74705SXin Li  return self;
50*67e74705SXin Li}
51*67e74705SXin Li
52*67e74705SXin Li- (id) initWithIntGood: (int)inInt {
53*67e74705SXin Li    if (self = [super initWithInt: inInt]) {
54*67e74705SXin Li      self.x = inInt;
55*67e74705SXin Li    }
56*67e74705SXin Li    return self;
57*67e74705SXin Li}
58*67e74705SXin Li+ (void) test {
59*67e74705SXin Li  Cell *sharedCell1 = [[Cell alloc] init];
60*67e74705SXin Li  [sharedCell1 release];
61*67e74705SXin Li  Cell *sharedCell2 = [[Cell alloc] initWithInt: 3];
62*67e74705SXin Li  [sharedCell2 release];
63*67e74705SXin Li  Cell *sharedCell3 = [[Cell alloc] initWithIntGood: 3];
64*67e74705SXin Li  [sharedCell3 release];
65*67e74705SXin Li}
66*67e74705SXin Li
67*67e74705SXin Li@end
68*67e74705SXin Li
69