xref: /aosp_15_r20/external/clang/test/Analysis/CFDateGC.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s  -Wno-implicit-function-declaration
2*67e74705SXin Li
3*67e74705SXin Li//===----------------------------------------------------------------------===//
4*67e74705SXin Li// The following code is reduced using delta-debugging from
5*67e74705SXin Li// Foundation.h and CoreFoundation.h (Mac OS X).
6*67e74705SXin Li//
7*67e74705SXin Li// It includes the basic definitions for the test cases below.
8*67e74705SXin Li// Not directly including [Core]Foundation.h directly makes this test case
9*67e74705SXin Li// both svelte and portable to non-Mac platforms.
10*67e74705SXin Li//===----------------------------------------------------------------------===//
11*67e74705SXin Li
12*67e74705SXin Litypedef const void * CFTypeRef;
13*67e74705SXin Livoid CFRelease(CFTypeRef cf);
14*67e74705SXin LiCFTypeRef CFRetain(CFTypeRef cf);
15*67e74705SXin LiCFTypeRef CFMakeCollectable(CFTypeRef cf);
16*67e74705SXin Litypedef const struct __CFAllocator * CFAllocatorRef;
17*67e74705SXin Litypedef double CFTimeInterval;
18*67e74705SXin Litypedef CFTimeInterval CFAbsoluteTime;
19*67e74705SXin Litypedef const struct __CFDate * CFDateRef;
20*67e74705SXin Liextern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
21*67e74705SXin Liextern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
22*67e74705SXin Litypedef struct objc_object {} *id;
23*67e74705SXin Litypedef signed char BOOL;
24*67e74705SXin Listatic __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) { return 0; }
25*67e74705SXin Li@protocol NSObject  - (BOOL)isEqual:(id)object;
26*67e74705SXin Li- (oneway void)release;
27*67e74705SXin Li- (id)retain;
28*67e74705SXin Li@end
29*67e74705SXin Li@class NSArray;
30*67e74705SXin Li
31*67e74705SXin Li//===----------------------------------------------------------------------===//
32*67e74705SXin Li// Test cases.
33*67e74705SXin Li//===----------------------------------------------------------------------===//
34*67e74705SXin Li
35*67e74705SXin LiCFAbsoluteTime CFAbsoluteTimeGetCurrent();
36*67e74705SXin Li
37*67e74705SXin LiCFAbsoluteTime f1_use_after_release() {
38*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
39*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t);
40*67e74705SXin Li  CFRetain(date);
41*67e74705SXin Li  [NSMakeCollectable(date) release];
42*67e74705SXin Li  CFDateGetAbsoluteTime(date); // no-warning
43*67e74705SXin Li  CFRelease(date);
44*67e74705SXin Li  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released}}
45*67e74705SXin Li  return t;
46*67e74705SXin Li}
47*67e74705SXin Li
48*67e74705SXin Li// The following two test cases verifies that CFMakeCollectable is a no-op
49*67e74705SXin Li// in non-GC mode and a "release" in GC mode.
50*67e74705SXin LiCFAbsoluteTime f2_use_after_release() {
51*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
52*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t);
53*67e74705SXin Li  CFRetain(date);
54*67e74705SXin Li  [(id) CFMakeCollectable(date) release];
55*67e74705SXin Li  CFDateGetAbsoluteTime(date); // no-warning
56*67e74705SXin Li  CFRelease(date);
57*67e74705SXin Li  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released}}
58*67e74705SXin Li  return t;
59*67e74705SXin Li}
60*67e74705SXin Li
61*67e74705SXin LiCFAbsoluteTime f2_noleak() {
62*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
63*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t);
64*67e74705SXin Li  CFRetain(date);
65*67e74705SXin Li  [(id) CFMakeCollectable(date) release];
66*67e74705SXin Li  CFDateGetAbsoluteTime(date); // no-warning
67*67e74705SXin Li  t = CFDateGetAbsoluteTime(date);  // no-warning
68*67e74705SXin Li  CFRelease(date); // no-warning
69*67e74705SXin Li  return t;
70*67e74705SXin Li}
71*67e74705SXin Li
72*67e74705SXin Livoid f3_leak_with_gc() {
73*67e74705SXin Li  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning 2 {{leak}}
74*67e74705SXin Li  [[(id) date retain] release];
75*67e74705SXin Li}
76*67e74705SXin Li
77*67e74705SXin Li// The following test case verifies that we "stop tracking" a retained object
78*67e74705SXin Li// when it is passed as an argument to an implicitly defined function.
79*67e74705SXin LiCFAbsoluteTime f4() {
80*67e74705SXin Li  CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
81*67e74705SXin Li  CFDateRef date = CFDateCreate(0, t);
82*67e74705SXin Li  CFRetain(date);
83*67e74705SXin Li  some_implicitly_defined_function_stop_tracking(date); // no-warning
84*67e74705SXin Li  return t;
85*67e74705SXin Li}
86