xref: /aosp_15_r20/external/clang/test/Analysis/retain-release-region-store.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
2*67e74705SXin Li
3*67e74705SXin Li//===----------------------------------------------------------------------===//
4*67e74705SXin Li// The following code is reduced using delta-debugging from
5*67e74705SXin Li// Foundation.h (Mac OS X).
6*67e74705SXin Li//
7*67e74705SXin Li// It includes the basic definitions for the test cases below.
8*67e74705SXin Li// Not including Foundation.h directly makes this test case both svelte and
9*67e74705SXin Li// portable to non-Mac platforms.
10*67e74705SXin Li//===----------------------------------------------------------------------===//
11*67e74705SXin Li
12*67e74705SXin Litypedef unsigned int __darwin_natural_t;
13*67e74705SXin Litypedef unsigned long UInt32;
14*67e74705SXin Litypedef signed long CFIndex;
15*67e74705SXin Litypedef const void * CFTypeRef;
16*67e74705SXin Litypedef const struct __CFString * CFStringRef;
17*67e74705SXin Litypedef const struct __CFAllocator * CFAllocatorRef;
18*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorDefault;
19*67e74705SXin Liextern CFTypeRef CFRetain(CFTypeRef cf);
20*67e74705SXin Liextern void CFRelease(CFTypeRef cf);
21*67e74705SXin Litypedef struct {
22*67e74705SXin Li}
23*67e74705SXin LiCFArrayCallBacks;
24*67e74705SXin Liextern const CFArrayCallBacks kCFTypeArrayCallBacks;
25*67e74705SXin Litypedef const struct __CFArray * CFArrayRef;
26*67e74705SXin Litypedef struct __CFArray * CFMutableArrayRef;
27*67e74705SXin Liextern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
28*67e74705SXin Liextern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
29*67e74705SXin Litypedef const struct __CFDictionary * CFDictionaryRef;
30*67e74705SXin Litypedef UInt32 CFStringEncoding;
31*67e74705SXin Lienum {
32*67e74705SXin LikCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
33*67e74705SXin Liextern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
34*67e74705SXin Litypedef double CFTimeInterval;
35*67e74705SXin Litypedef CFTimeInterval CFAbsoluteTime;
36*67e74705SXin Litypedef const struct __CFDate * CFDateRef;
37*67e74705SXin Liextern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
38*67e74705SXin Liextern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
39*67e74705SXin Litypedef __darwin_natural_t natural_t;
40*67e74705SXin Litypedef natural_t mach_port_name_t;
41*67e74705SXin Litypedef mach_port_name_t mach_port_t;
42*67e74705SXin Litypedef signed char BOOL;
43*67e74705SXin Litypedef struct _NSZone NSZone;
44*67e74705SXin Li@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
45*67e74705SXin Li@protocol NSObject
46*67e74705SXin Li- (BOOL)isEqual:(id)object;
47*67e74705SXin Li- (id)retain;
48*67e74705SXin Li- (oneway void)release;
49*67e74705SXin Li@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
50*67e74705SXin Li@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
51*67e74705SXin Li@end
52*67e74705SXin Li@interface NSObject <NSObject> {}
53*67e74705SXin Li- (id)init;
54*67e74705SXin Li+ (id)allocWithZone:(NSZone *)zone;
55*67e74705SXin Li+ (id)alloc;
56*67e74705SXin Li- (void)dealloc;
57*67e74705SXin Li@end
58*67e74705SXin Litypedef float CGFloat;
59*67e74705SXin Litypedef double NSTimeInterval;
60*67e74705SXin Li@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
61*67e74705SXin Li@end      enum {
62*67e74705SXin LiNSObjCNoType = 0,     NSObjCVoidType = 'v',     NSObjCCharType = 'c',     NSObjCShortType = 's',     NSObjCLongType = 'l',     NSObjCLonglongType = 'q',     NSObjCFloatType = 'f',     NSObjCDoubleType = 'd',      NSObjCBoolType = 'B',      NSObjCSelectorType = ':',     NSObjCObjectType = '@',     NSObjCStructType = '{',     NSObjCPointerType = '^',     NSObjCStringType = '*',     NSObjCArrayType = '[',     NSObjCUnionType = '(',     NSObjCBitfield = 'b' }
63*67e74705SXin Li__attribute__((deprecated));
64*67e74705SXin Litypedef int kern_return_t;
65*67e74705SXin Litypedef kern_return_t mach_error_t;
66*67e74705SXin Litypedef mach_port_t io_object_t;
67*67e74705SXin Litypedef io_object_t io_service_t;
68*67e74705SXin Litypedef struct __DASession * DASessionRef;
69*67e74705SXin Liextern DASessionRef DASessionCreate( CFAllocatorRef allocator );
70*67e74705SXin Litypedef struct __DADisk * DADiskRef;
71*67e74705SXin Liextern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
72*67e74705SXin Liextern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
73*67e74705SXin Liextern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
74*67e74705SXin Liextern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
75*67e74705SXin Li@interface NSAppleEventManager : NSObject {
76*67e74705SXin Li}
77*67e74705SXin Li@end enum {
78*67e74705SXin LikDAReturnSuccess = 0,     kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
79*67e74705SXin Litypedef mach_error_t DAReturn;
80*67e74705SXin Litypedef const struct __DADissenter * DADissenterRef;
81*67e74705SXin Liextern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
82*67e74705SXin Li@interface NSNumber : NSObject
83*67e74705SXin Li- (id)initWithInt:(int)value;
84*67e74705SXin Li@end
85*67e74705SXin Litypedef unsigned long NSUInteger;
86*67e74705SXin Li@interface NSArray : NSObject
87*67e74705SXin Li-(id) initWithObjects:(const id *)objects count:(NSUInteger) cnt;
88*67e74705SXin Li@end
89*67e74705SXin Li
90*67e74705SXin Li//===----------------------------------------------------------------------===//
91*67e74705SXin Li// Test cases.
92*67e74705SXin Li//===----------------------------------------------------------------------===//
93*67e74705SXin Li
94*67e74705SXin Li// Test to see if we *issue* an error when we store the pointer
95*67e74705SXin Li// to a struct.  This differs from basic store.
96*67e74705SXin Li
97*67e74705SXin LiCFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
98*67e74705SXin Li
99*67e74705SXin Listruct foo {
100*67e74705SXin Li  NSDate* f;
101*67e74705SXin Li};
102*67e74705SXin Li
103*67e74705SXin Li// FIXME: We should be warning about a use-after-free here, but we
104*67e74705SXin Li// temporarily "escape" retain counted objects stored to structs very eagerly
105*67e74705SXin Li// until we can properly tell whether they have escaped via a return value
106*67e74705SXin Li// or not.
107*67e74705SXin LiCFAbsoluteTime f4() {
108*67e74705SXin Li  struct foo x;
109*67e74705SXin Li
110*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
111*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t);
112*67e74705SXin Li  [((NSDate*) date) retain];
113*67e74705SXin Li  CFRelease(date);
114*67e74705SXin Li  CFDateGetAbsoluteTime(date); // no-warning
115*67e74705SXin Li  x.f = (NSDate*) date;
116*67e74705SXin Li  [((NSDate*) date) release];
117*67e74705SXin Li  // FIXME: the following line should warn.
118*67e74705SXin Li  t = CFDateGetAbsoluteTime(date);   // no-warning
119*67e74705SXin Li  return t;
120*67e74705SXin Li}
121*67e74705SXin Li
122*67e74705SXin Li// Test that assigning to an self.ivar loses track of an object.
123*67e74705SXin Li// This is a temporary hack to reduce false positives.
124*67e74705SXin Li@interface Test3 : NSObject {
125*67e74705SXin Li  id myObj;
126*67e74705SXin Li}
127*67e74705SXin Li- (void)test_self_assign_ivar;
128*67e74705SXin Li@end
129*67e74705SXin Li
130*67e74705SXin Li@implementation Test3
131*67e74705SXin Li- (void)test_self_assign_ivar {
132*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
133*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t); // no-warning
134*67e74705SXin Li  myObj = (id) date;
135*67e74705SXin Li}
136*67e74705SXin Li@end
137*67e74705SXin Li
138*67e74705SXin Li//===------------------------------------------------------------------------------------------===//
139*67e74705SXin Li// <rdar://problem/7257223> (also <rdar://problem/7283470>) - False positive due to not invalidating
140*67e74705SXin Li//  the reference count of a tracked region that was itself invalidated.
141*67e74705SXin Li//===------------------------------------------------------------------------------------------===//
142*67e74705SXin Li
143*67e74705SXin Litypedef struct __rdar_7257223 { CFDateRef x; } RDar7257223;
144*67e74705SXin Livoid rdar_7257223_aux(RDar7257223 *p);
145*67e74705SXin Li
146*67e74705SXin LiCFDateRef rdar7257223_Create(void) {
147*67e74705SXin Li  RDar7257223 s;
148*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
149*67e74705SXin Li  s.x = CFDateCreate(0, t); // no-warning
150*67e74705SXin Li  rdar_7257223_aux(&s);
151*67e74705SXin Li  return s.x;
152*67e74705SXin Li}
153*67e74705SXin Li
154*67e74705SXin LiCFDateRef rdar7257223_Create_2(void) {
155*67e74705SXin Li  RDar7257223 s;
156*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
157*67e74705SXin Li  s.x = CFDateCreate(0, t); // no-warning
158*67e74705SXin Li  return s.x;
159*67e74705SXin Li}
160*67e74705SXin Li
161*67e74705SXin Livoid rdar7283470(void) {
162*67e74705SXin Li  NSNumber *numbers[] = {
163*67e74705SXin Li    [[NSNumber alloc] initWithInt:1], // no-warning
164*67e74705SXin Li    [[NSNumber alloc] initWithInt:2], // no-warning
165*67e74705SXin Li    [[NSNumber alloc] initWithInt:3], // no-warning
166*67e74705SXin Li    [[NSNumber alloc] initWithInt:4], // no-warning
167*67e74705SXin Li    [[NSNumber alloc] initWithInt:5]  // no-warning
168*67e74705SXin Li  };
169*67e74705SXin Li
170*67e74705SXin Li  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
171*67e74705SXin Li    [numbers[i] release];
172*67e74705SXin Li}
173*67e74705SXin Li
174*67e74705SXin Livoid rdar7283470_positive(void) {
175*67e74705SXin Li  NSNumber *numbers[] = {
176*67e74705SXin Li    [[NSNumber alloc] initWithInt:1], // expected-warning{{leak}}
177*67e74705SXin Li    [[NSNumber alloc] initWithInt:2], // expected-warning{{leak}}
178*67e74705SXin Li    [[NSNumber alloc] initWithInt:3], // expected-warning{{leak}}
179*67e74705SXin Li    [[NSNumber alloc] initWithInt:4], // expected-warning{{leak}}
180*67e74705SXin Li    [[NSNumber alloc] initWithInt:5]  // expected-warning{{leak}}
181*67e74705SXin Li  };
182*67e74705SXin Li}
183*67e74705SXin Li
184*67e74705SXin Livoid rdar7283470_2(void) {
185*67e74705SXin Li  NSNumber *numbers[] = {
186*67e74705SXin Li    [[NSNumber alloc] initWithInt:1], // no-warning
187*67e74705SXin Li    [[NSNumber alloc] initWithInt:2], // no-warning
188*67e74705SXin Li    [[NSNumber alloc] initWithInt:3], // no-warning
189*67e74705SXin Li    [[NSNumber alloc] initWithInt:4], // no-warning
190*67e74705SXin Li    [[NSNumber alloc] initWithInt:5]  // no-warning
191*67e74705SXin Li  };
192*67e74705SXin Li
193*67e74705SXin Li  NSArray *s_numbers =[[NSArray alloc] initWithObjects:&numbers[0] count:sizeof(numbers) / sizeof(numbers[0])];
194*67e74705SXin Li
195*67e74705SXin Li  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
196*67e74705SXin Li    [numbers[i] release];
197*67e74705SXin Li
198*67e74705SXin Li  [s_numbers release];
199*67e74705SXin Li}
200*67e74705SXin Li
201*67e74705SXin Livoid rdar7283470_2_positive(void) {
202*67e74705SXin Li  NSNumber *numbers[] = {
203*67e74705SXin Li    [[NSNumber alloc] initWithInt:1], // no-warning
204*67e74705SXin Li    [[NSNumber alloc] initWithInt:2], // no-warning
205*67e74705SXin Li    [[NSNumber alloc] initWithInt:3], // no-warning
206*67e74705SXin Li    [[NSNumber alloc] initWithInt:4], // no-warning
207*67e74705SXin Li    [[NSNumber alloc] initWithInt:5]  // no-warning
208*67e74705SXin Li  };
209*67e74705SXin Li
210*67e74705SXin Li  NSArray *s_numbers =[[NSArray alloc] initWithObjects: &numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; // expected-warning{{leak}}
211*67e74705SXin Li
212*67e74705SXin Li  for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i)
213*67e74705SXin Li    [numbers[i] release];
214*67e74705SXin Li}
215*67e74705SXin Li
216*67e74705SXin Livoid pr6699(int x) {
217*67e74705SXin Li  CFDateRef values[2];
218*67e74705SXin Li  values[0] = values[1] = 0;
219*67e74705SXin Li
220*67e74705SXin Li  if (x) {
221*67e74705SXin Li    CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
222*67e74705SXin Li    values[1] = CFDateCreate(0, t);
223*67e74705SXin Li  }
224*67e74705SXin Li
225*67e74705SXin Li  if (values[1]) {
226*67e74705SXin Li    // A bug in RegionStore::RemoveDeadBindings caused 'values[1]' to get prematurely
227*67e74705SXin Li    // pruned from the store.
228*67e74705SXin Li    CFRelease(values[1]); // no-warning
229*67e74705SXin Li  }
230*67e74705SXin Li}
231*67e74705SXin Li
232*67e74705SXin Li// <rdar://problem/8261992> Idempotent operation checker false positive with ObjC ivars
233*67e74705SXin Li@interface R8261992 : NSObject {
234*67e74705SXin Li  @package int myIvar;
235*67e74705SXin Li}
236*67e74705SXin Li@end
237*67e74705SXin Li
238*67e74705SXin Listatic void R8261992_ChangeMyIvar(R8261992 *tc) {
239*67e74705SXin Li    tc->myIvar = 5;
240*67e74705SXin Li}
241*67e74705SXin Li
242*67e74705SXin Livoid R8261992_test(R8261992 *tc) {
243*67e74705SXin Li  int temp = tc->myIvar;
244*67e74705SXin Li  // The ivar binding for tc->myIvar gets invalidated.
245*67e74705SXin Li  R8261992_ChangeMyIvar(tc);
246*67e74705SXin Li  tc->myIvar = temp; // no-warning
247*67e74705SXin Li  tc = [[R8261992 alloc] init];
248*67e74705SXin Li  temp = tc->myIvar; // no-warning
249*67e74705SXin Li  // The ivar binding for tc->myIvar gets invalidated.
250*67e74705SXin Li  R8261992_ChangeMyIvar(tc);
251*67e74705SXin Li  tc->myIvar = temp;
252*67e74705SXin Li  [tc release]; // no-warning
253*67e74705SXin Li  // did we analyze this?
254*67e74705SXin Li  int *p = 0x0;
255*67e74705SXin Li  *p = 0xDEADBEEF; // expected-warning{{null}}
256*67e74705SXin Li}
257*67e74705SXin Li
258