reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
// 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
// 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

typedef __typeof(sizeof(int)) size_t;

#define HAS_ARC __has_feature(objc_arc)

typedef unsigned long long CFOptionFlags;
typedef signed long long CFIndex;

typedef CFIndex CFPropertyListFormat; enum {
    kCFPropertyListOpenStepFormat = 1,
    kCFPropertyListXMLFormat_v1_0 = 100,
    kCFPropertyListBinaryFormat_v1_0 = 200
};

typedef const struct __CFAllocator * CFAllocatorRef;
extern const CFAllocatorRef kCFAllocatorDefault;
typedef struct __CFDictionary * CFDictionaryRef;
typedef struct __CFError * CFErrorRef;
typedef struct __CFDataRef * CFDataRef;
typedef void * CFPropertyListRef;

CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error);

typedef signed char BOOL;
typedef struct _NSZone NSZone;
@class NSDictionary;
@class NSData;
@class NSString;

@protocol NSObject
- (BOOL)isEqual:(id)object;
- (id)retain;
- (oneway void)release;
- (id)autorelease;
- (NSString *)description;
- (id)init;
@end
@interface NSObject <NSObject> {}
+ (id)allocWithZone:(NSZone *)zone;
+ (id)alloc;
+ (id)new;
- (void)dealloc;
@end

@interface NSDictionary : NSObject
@end

#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED

@protocol OS_dispatch_object
@end
@protocol OS_dispatch_data <OS_dispatch_object>
@end
@protocol OS_dispatch_queue <OS_dispatch_object>
@end

typedef NSObject<OS_dispatch_object> *dispatch_object_t;
typedef NSObject<OS_dispatch_data> *dispatch_data_t;
typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;

typedef void (^dispatch_block_t)(void);

dispatch_queue_t dispatch_get_main_queue(void);

DISPATCH_RETURNS_RETAINED dispatch_data_t
dispatch_data_create(const void *buffer, size_t size,
                     dispatch_queue_t _Nullable queue,
                     dispatch_block_t _Nullable destructor);

void _dispatch_object_validate(dispatch_object_t object);

#define dispatch_retain(object) \
  __extension__({ dispatch_object_t _o = (object); \
                  _dispatch_object_validate(_o); \
                  (void)[_o retain]; })
#define dispatch_release(object) \
  __extension__({ dispatch_object_t _o = (object); \
                  _dispatch_object_validate(_o); \
                  [_o release]; })


@interface SomeClass
@end

@implementation SomeClass
- (NSDictionary *)copyTestWithBridgeReturningRetainable:(NSData *)plistData {
  CFErrorRef error;
  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
#if HAS_ARC
      // expected-note@-2 {{Call to function 'CFPropertyListCreateWithData' returns a Core Foundation object of type 'CFPropertyListRef' with a +1 retain count}}
#endif
  return (__bridge NSDictionary *)testDict;
#if HAS_ARC
      // expected-warning@-2 {{Potential leak of an object stored into 'testDict'}}
      // expected-note@-3 {{Object leaked: object allocated and stored into 'testDict' is returned from a method managed by Automatic Reference Counting}}
#endif
}

- (NSDictionary *)copyTestWithoutBridgeReturningRetainable:(NSData *)plistData {
  NSDictionary *testDict = [[NSDictionary alloc] init];
  return testDict; // no-warning
}

- (NSDictionary *)copyTestWithBridgeTransferReturningRetainable:(NSData *)plistData {
  CFErrorRef error;
  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
  return (__bridge_transfer NSDictionary *)testDict; // no-warning under ARC
#if !HAS_ARC
      // expected-warning@-2 {{'__bridge_transfer' casts have no effect when not using ARC}} // Warning from Sema
#endif
}

- (CFDictionaryRef)copyTestReturningCoreFoundation:(NSData *)plistData {
  CFErrorRef error;
  CFDictionaryRef testDict = CFPropertyListCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)plistData, 0, 0, &error);
  return testDict;
}
@end

int buf[1024];

void libdispatch_leaked_data() {
  dispatch_data_t data = dispatch_data_create(buf, 1024,
                                              dispatch_get_main_queue(), ^{});
}
#if !HAS_ARC
  // expected-warning@-2{{Potential leak of an object stored into 'data'}}
  // expected-note@-5{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}}
  // 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}}
#endif

void libdispatch_dispatch_released_data() {
  dispatch_data_t data = dispatch_data_create(buf, 1024,
                                              dispatch_get_main_queue(), ^{});
#if !HAS_ARC
  dispatch_release(data); // no-warning
#endif
}

void libdispatch_objc_released_data() {
  dispatch_data_t data = dispatch_data_create(buf, 1024,
                                              dispatch_get_main_queue(), ^{});
#if !HAS_ARC
  [data release]; // no-warning
#endif
}

void libdispatch_leaked_retained_data() {
  dispatch_data_t data = dispatch_data_create(buf, 1024,
                                              dispatch_get_main_queue(), ^{});
#if !HAS_ARC
  dispatch_retain(data);
  [data release];
#endif
}
#if !HAS_ARC
// expected-warning@-2{{Potential leak of an object stored into 'data'}}
// expected-note@-9{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}}
// expected-note@-7{{Reference count incremented. The object now has a +2 retain count}}
// expected-note@-7{{Reference count decremented. The object now has a +1 retain count}}
// 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}}
#endif