[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / Analysis / objc-arc.m
blob2ed210f318262e2422e043ae76a97ed8903ff8c4
1 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -fobjc-arc -analyzer-output=plist-multi-file -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t.plist %s
2 // RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/objc-arc.m.plist -
4 typedef signed char BOOL;
5 typedef struct _NSZone NSZone;
6 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
7 typedef unsigned long NSUInteger;
9 @protocol NSObject
10 - (BOOL)isEqual:(id)object;
11 @end
12 @protocol NSCopying
13 - (id)copyWithZone:(NSZone *)zone;
14 @end
15 @protocol NSCoding;
16 @protocol NSMutableCopying;
17 @protocol NSFastEnumeration
18 - (void)encodeWithCoder:(NSCoder *)aCoder;
19 @end
20 @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
21 @end
22 @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
23 @end
24 @interface NSObject <NSObject> {}
25 + (id)alloc;
26 - (id)init;
27 - (NSString *)description;
28 @end
29 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
30 - (NSUInteger)count;
31 - (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt;
32 + (id)arrayWithObject:(id)anObject;
33 + (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
34 + (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
35 - (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1)));
36 - (id)initWithArray:(NSArray *)array;
37 @end
39 typedef const struct __CFAllocator * CFAllocatorRef;
40 extern const CFAllocatorRef kCFAllocatorDefault;
41 typedef double CFTimeInterval;
42 typedef CFTimeInterval CFAbsoluteTime;
43 extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
44 typedef const struct __CFDate * CFDateRef;
45 extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
47 typedef const void* objc_objectptr_t;
48 __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer);
49 __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer);
51 // Test the analyzer is working at all.
52 void test_working(void) {
53   int *p = 0;
54   *p = 0xDEADBEEF; // expected-warning {{null}}
57 // Test that in ARC mode that blocks are correctly automatically copied
58 // and not flagged as warnings by the analyzer.
59 typedef void (^Block)(void);
60 void testblock_bar(int x);
62 Block testblock_foo(int x) {
63   Block b = ^{ testblock_bar(x); };
64   return b; // no-warning
67 Block testblock_baz(int x) {
68   return ^{ testblock_bar(x); }; // no-warning
71 Block global_block;
73 void testblock_qux(int x) {
74   global_block = ^{ testblock_bar(x); }; // no-warning
77 // Test that Objective-C pointers are null initialized.
78 void test_nil_initialized(void) {
79   id x;
80   if (x == 0)
81     return;
82   int *p = 0;
83   *p = 0xDEADBEEF; // no-warning
86 // Test that we don't flag leaks of Objective-C objects.
87 void test_alloc(void) {
88   [NSObject alloc]; // no-warning
91 // Test that CF allocations are still caught as leaks.
92 void test_cf_leak(void) {
93   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
94   CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}}
95   (void) date;
98 // Test that 'init' methods do not try to claim ownerhip of an *unowned* allocated object
99 // in ARC mode.
100 @interface RDar9424890_A :  NSObject
101 - (id)initWithCleaner:(int)pop mop:(NSString *)mop ;
102 - (RDar9424890_A *)rdar9424890:(NSString *)identifier;
103 @end
104 @interface RDar9424890_B : NSObject
105 @end
106 @implementation RDar9424890_B
107 - (RDar9424890_A *)obj:(RDar9424890_A *)obj {
108   static NSString *WhizFiz = @"WhizFiz";
109   RDar9424890_A *cell = [obj rdar9424890:WhizFiz];
110   if (cell == ((void*)0)) {
111     cell = [[RDar9424890_A alloc] initWithCleaner:0 mop:WhizFiz]; // no-warning
112   }
113   return cell;
115 @end
117 // Test that dead store checking works in the prescence of "cleanups" in the AST.
118 void rdar9424882(void) {
119   id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
122 // Test 
123 typedef const void *CFTypeRef;
124 typedef const struct __CFString *CFStringRef;
126 @interface NSString : NSObject
127 - (id) self;
128 @end
130 CFTypeRef CFCreateSomething(void);
131 CFStringRef CFCreateString(void);
132 CFTypeRef CFGetSomething(void);
133 CFStringRef CFGetString(void);
135 id CreateSomething(void);
136 NSString *CreateNSString(void);
138 void from_cf(void) {
139   id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}}
140   id obj2 = (__bridge_transfer NSString*)CFCreateString();
141   [obj2 self]; // Add a use, to show we can use the object after it has been transferred.
142   id obj3 = (__bridge id)CFGetSomething();
143   [obj3 self]; // Add a use, to show we can use the object after it has been bridged.
144   id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}}
145   id obj5 = (__bridge id)CFCreateSomething(); // expected-warning{{never read}} expected-warning{{leak}}
146   id obj6 = (__bridge NSString*)CFCreateString(); // expected-warning{{never read}} expected-warning{{leak}}
149 void to_cf(id obj) {
150   CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning{{never read}}
151   CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning{{never read}}
152   CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning{{never read}}
153   CFStringRef cf4 = (__bridge CFStringRef)CreateNSString();  // expected-warning{{never read}}
156 void test_objc_retainedObject(void) {
157   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
158   CFDateRef date = CFDateCreate(0, t);
159   id x = objc_retainedObject(date);
160   (void) x;
163 void test_objc_unretainedObject(void) {
164   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
165   CFDateRef date = CFDateCreate(0, t);  // expected-warning {{Potential leak}}
166   id x = objc_unretainedObject(date);
167   (void) x;
170 // Previously this resulted in a "return of stack address" warning.
171 id test_return(void) {
172   id x = (__bridge_transfer id) CFCreateString();
173   return x; // no-warning
176 void test_objc_arrays(void) {
177     { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY
178         NSObject *o = [[NSObject alloc] init];
179         NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0];
180         [a description];
181         [o description];
182     }
184     { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY
185         NSObject *o = [[NSObject alloc] init];
186         NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0];
187         NSArray *a2 = [[NSArray alloc] initWithArray:a1];
188         [a2 description];
189         [o description];
190     }
192     { // CASE THREE -- OBJECT IN RETAINED @[]
193         NSObject *o = [[NSObject alloc] init];
194         NSArray *a3 = @[o];
195         [a3 description];
196         [o description];
197     }
198     {
199       // CASE 4, verify analyzer still working.
200       CFCreateString(); // expected-warning {{leak}}
201     }
204 // dispatch_set_context and ARC.
205 __attribute__((cf_returns_retained)) CFTypeRef CFBridgingRetain(id X);
206 typedef void* dispatch_object_t;
207 void dispatch_set_context(dispatch_object_t object, const void *context);
209 void rdar11059275(dispatch_object_t object) {
210   NSObject *o = [[NSObject alloc] init];
211   dispatch_set_context(object, CFBridgingRetain(o)); // no-warning  
213 void rdar11059275_positive(void) {
214   NSObject *o = [[NSObject alloc] init]; // expected-warning {{leak}}
215   CFBridgingRetain(o);
217 void rdar11059275_negative(void) {
218   NSObject *o = [[NSObject alloc] init]; // no-warning
219   (void) o;
222 __attribute__((ns_returns_retained)) id rdar14061675_helper(void) {
223   return [[NSObject alloc] init];
226 id rdar14061675(void) {
227   // ARC produces an implicit cast here. We need to make sure the combination
228   // of that and the inlined call don't produce a spurious edge cycle.
229   id result = rdar14061675_helper();
230   *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}}
231   return result;
234 typedef const void * CFTypeRef;
235 typedef const struct __CFString * CFStringRef;
236 typedef const struct __CFAllocator * CFAllocatorRef;
237 extern const CFAllocatorRef kCFAllocatorDefault;
239 extern CFTypeRef CFRetain(CFTypeRef cf);
240 extern void CFRelease(CFTypeRef cf);
243 void check_bridge_retained_cast(void) {
244     NSString *nsStr = [[NSString alloc] init];
245     CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr;
246     CFRelease(cfStr); // no-warning
249 @interface A;
250 @end
252 void check_bridge_to_non_cocoa(CFStringRef s) {
253   A *a = (__bridge_transfer A *) s; // no-crash
256 struct B;
258 struct B * check_bridge_to_non_cf(void) {
259   NSString *s = [[NSString alloc] init];
260   return (__bridge struct B*) s;