1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
2// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
3
4typedef __typeof(sizeof(int)) size_t;
5
6#define HAS_ARC __has_feature(objc_arc)
7
8typedef unsigned long long CFOptionFlags;
9typedef signed long long CFIndex;
10
11typedef CFIndex CFPropertyListFormat; enum {
12    kCFPropertyListOpenStepFormat = 1,
13    kCFPropertyListXMLFormat_v1_0 = 100,
14    kCFPropertyListBinaryFormat_v1_0 = 200
15};
16
17typedef const struct __CFAllocator * CFAllocatorRef;
18extern const CFAllocatorRef kCFAllocatorDefault;
19typedef struct __CFDictionary * CFDictionaryRef;
20typedef struct __CFError * CFErrorRef;
21typedef struct __CFDataRef * CFDataRef;
22typedef void * CFPropertyListRef;
23
24CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error);
25
26typedef signed char BOOL;
27typedef struct _NSZone NSZone;
28@class NSDictionary;
29@class NSData;
30@class NSString;
31
32@protocol NSObject
33- (BOOL)isEqual:(id)object;
34- (id)retain;
35- (oneway void)release;
36- (id)autorelease;
37- (NSString *)description;
38- (id)init;
39@end
40@interface NSObject <NSObject> {}
41+ (id)allocWithZone:(NSZone *)zone;
42+ (id)alloc;
43+ (id)new;
44- (void)dealloc;
45@end
46
47@interface NSDictionary : NSObject
48@end
49
50#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
51#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
52
53@protocol OS_dispatch_object
54@end
55@protocol OS_dispatch_data <OS_dispatch_object>
56@end
57@protocol OS_dispatch_queue <OS_dispatch_object>
58@end
59
60typedef NSObject<OS_dispatch_object> *dispatch_object_t;
61typedef NSObject<OS_dispatch_data> *dispatch_data_t;
62typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;
63
64typedef void (^dispatch_block_t)(void);
65
66dispatch_queue_t dispatch_get_main_queue(void);
67
68DISPATCH_RETURNS_RETAINED dispatch_data_t
69dispatch_data_create(const void *buffer, size_t size,
70                     dispatch_queue_t _Nullable queue,
71                     dispatch_block_t _Nullable destructor);
72
73void _dispatch_object_validate(dispatch_object_t object);
74
75#define dispatch_retain(object) \
76  __extension__({ dispatch_object_t _o = (object); \
77                  _dispatch_object_validate(_o); \
78                  (void)[_o retain]; })
79#define dispatch_release(object) \
80  __extension__({ dispatch_object_t _o = (object); \
81                  _dispatch_object_validate(_o); \
82                  [_o release]; })
83
84
85@interface SomeClass
86@end
87
88@implementation SomeClass
89- (NSDictionary *)copyTestWithBridgeReturningRetainable:(NSData *)plistData {
90  CFErrorRef error;
91  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
92#if HAS_ARC
93      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type 'CFPropertyListRef' with a +1 retain count}}
94#endif
95  return (__bridge NSDictionary *)testDict;
96#if HAS_ARC
97      // expected-warning@-2 {{Potential leak of an object stored into 'testDict'}}
98      // expected-note@-3 {{Object leaked: object allocated and stored into 'testDict' is returned from a method managed by Automatic Reference Counting}}
99#endif
100}
101
102- (NSDictionary *)copyTestWithoutBridgeReturningRetainable:(NSData *)plistData {
103  NSDictionary *testDict = [[NSDictionary alloc] init];
104  return testDict; // no-warning
105}
106
107- (NSDictionary *)copyTestWithBridgeTransferReturningRetainable:(NSData *)plistData {
108  CFErrorRef error;
109  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
110  return (__bridge_transfer NSDictionary *)testDict; // no-warning under ARC
111#if !HAS_ARC
112      // expected-warning@-2 {{'__bridge_transfer' casts have no effect when not using ARC}} // Warning from Sema
113#endif
114}
115
116- (CFDictionaryRef)copyTestReturningCoreFoundation:(NSData *)plistData {
117  CFErrorRef error;
118  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
119  return testDict;
120}
121@end
122
123int buf[1024];
124
125void libdispatch_leaked_data() {
126  dispatch_data_t data = dispatch_data_create(buf, 1024,
127                                              dispatch_get_main_queue(), ^{});
128}
129#if !HAS_ARC
130  // expected-warning@-2{{Potential leak of an object stored into 'data'}}
131  // expected-note@-5{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}}
132  // expected-note@-4{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}}
133#endif
134
135void libdispatch_dispatch_released_data() {
136  dispatch_data_t data = dispatch_data_create(buf, 1024,
137                                              dispatch_get_main_queue(), ^{});
138#if !HAS_ARC
139  dispatch_release(data); // no-warning
140#endif
141}
142
143void libdispatch_objc_released_data() {
144  dispatch_data_t data = dispatch_data_create(buf, 1024,
145                                              dispatch_get_main_queue(), ^{});
146#if !HAS_ARC
147  [data release]; // no-warning
148#endif
149}
150
151void libdispatch_leaked_retained_data() {
152  dispatch_data_t data = dispatch_data_create(buf, 1024,
153                                              dispatch_get_main_queue(), ^{});
154#if !HAS_ARC
155  dispatch_retain(data);
156  [data release];
157#endif
158}
159#if !HAS_ARC
160// expected-warning@-2{{Potential leak of an object stored into 'data'}}
161// expected-note@-9{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}}
162// expected-note@-7{{Reference count incremented. The object now has a +2 retain count}}
163// expected-note@-7{{Reference count decremented. The object now has a +1 retain count}}
164// expected-note@-6{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}}
165#endif
166