brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 47203cb Raw
312 lines · plain
1// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}2// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.RetainPtrCtorAdoptChecker -fobjc-arc -verify %s3 4#include "objc-mock-types.h"5 6CFTypeRef CFCopyArray(CFArrayRef);7 8void basic_correct() {9  auto ns1 = adoptNS([SomeObj alloc]);10  auto ns2 = adoptNS([[SomeObj alloc] init]);11  RetainPtr<SomeObj> ns3 = [ns1.get() next];12  auto ns4 = adoptNS([ns3 mutableCopy]);13  auto ns5 = adoptNS([ns3 copyWithValue:3]);14  auto ns6 = retainPtr([ns3 next]);15  CFMutableArrayRef cf1 = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10));16  auto cf2 = adoptCF(SecTaskCreateFromSelf(kCFAllocatorDefault));17  auto cf3 = adoptCF(checked_cf_cast<CFArrayRef>(CFCopyArray(cf1)));18}19 20CFMutableArrayRef provide_cf();21 22void basic_wrong() {23  RetainPtr<SomeObj> ns1 = [[SomeObj alloc] init];24  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}25  auto ns2 = adoptNS([ns1.get() next]);26  // expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}27  RetainPtr<CFMutableArrayRef> cf1 = CFArrayCreateMutable(kCFAllocatorDefault, 10);28  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}29  RetainPtr<CFMutableArrayRef> cf2 = adoptCF(provide_cf());30  // expected-warning@-1{{Incorrect use of adoptCF. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}31  RetainPtr<CFTypeRef> cf3 = SecTaskCreateFromSelf(kCFAllocatorDefault);32  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}33  CFCopyArray(cf1);34  // expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}35}36 37void basic_correct_arc() {38  auto *obj = [[SomeObj alloc] init];39  [obj doWork];40}41 42@implementation SomeObj {43  NSNumber *_number;44  SomeObj *_next;45  SomeObj *_other;46}47 48- (instancetype)_init {49  self = [super init];50  _number = nil;51  _next = nil;52  _other = nil;53  return self;54}55 56- (SomeObj *)mutableCopy {57  auto *copy = [[SomeObj alloc] init];58  [copy setValue:_number];59  [copy setNext:_next];60  [copy setOther:_other];61  return copy;62}63 64- (SomeObj *)copyWithValue:(int)value {65  auto *copy = [[SomeObj alloc] init];66  [copy setValue:_number];67  [copy setNext:_next];68  [copy setOther:_other];69  return copy;70}71 72- (void)doWork {73  _number = [[NSNumber alloc] initWithInt:5];74}75 76- (SomeObj *)other {77  return _other;78}79 80- (void)setOther:(SomeObj *)obj {81  _other = obj;82}83 84- (SomeObj *)next {85  return _next;86}87 88- (void)setNext:(SomeObj *)obj {89  _next = obj;90}91 92- (int)value {93  return [_number intValue];94}95 96- (void)setValue:(NSNumber *)value {97  _number = value;98}99 100@end;101 102RetainPtr<CVPixelBufferRef> cf_out_argument() {103  auto surface = adoptCF(IOSurfaceCreate(nullptr));104  CVPixelBufferRef rawBuffer = nullptr;105  auto status = CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface.get(), nullptr, &rawBuffer);106  return adoptCF(rawBuffer);107}108 109RetainPtr<SomeObj> return_nullptr() {110  return nullptr;111}112 113RetainPtr<SomeObj> return_retainptr() {114  RetainPtr<SomeObj> foo;115  return foo;116}117 118CFTypeRef CopyValueForSomething();119 120void cast_retainptr() {121  RetainPtr<NSObject> foo;122  RetainPtr<SomeObj> bar = static_cast<SomeObj*>(foo);123 124  auto baz = adoptCF(CopyValueForSomething()).get();125  RetainPtr<CFArrayRef> v = static_cast<CFArrayRef>(baz);126}127 128CFTypeRef CopyWrapper() {129  return CopyValueForSomething();130}131 132CFTypeRef LeakWrapper() {133  return CopyValueForSomething();134  // expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}135}136 137NSArray *makeArray() NS_RETURNS_RETAINED {138  return CFBridgingRelease(CFArrayCreateMutable(kCFAllocatorDefault, 10));139}140 141extern Class (*getNSArrayClass)();142NSArray *allocArrayInstance() NS_RETURNS_RETAINED {143  return [[getNSArrayClass() alloc] init];144}145 146extern int (*GetObj)(CF_RETURNS_RETAINED CFTypeRef* objOut);147RetainPtr<CFTypeRef> getObject() {148  CFTypeRef obj = nullptr;149  if (GetObj(&obj))150    return nullptr;151  return adoptCF(obj);152}153 154CFArrayRef CreateSingleArray(CFStringRef);155CFArrayRef CreateSingleArray(CFDictionaryRef);156CFArrayRef CreateSingleArray(CFArrayRef);157template <typename ElementType>158static RetainPtr<CFArrayRef> makeArrayWithSingleEntry(ElementType arg) {159  return adoptCF(CreateSingleArray(arg));160}161 162void callMakeArayWithSingleEntry() {163  auto dictionary = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, nullptr, nullptr, 0));164  makeArrayWithSingleEntry(dictionary.get());165}166 167SomeObj* allocSomeObj() CF_RETURNS_RETAINED;168 169void adopt_retainptr() {170  RetainPtr<NSObject> foo = adoptNS([[SomeObj alloc] init]);171  auto bar = adoptNS([allocSomeObj() init]);172}173 174RetainPtr<CFArrayRef> return_arg(CFArrayRef arg) {175  return arg;176}177 178class MemberInit {179public:180  MemberInit(RetainPtr<CFMutableArrayRef>&& array, NSString *str, CFRunLoopRef runLoop)181    : m_array(array)182    , m_str(str)183    , m_runLoop(runLoop)184  { }185 186private:187  RetainPtr<CFMutableArrayRef> m_array;188  RetainPtr<NSString> m_str;189  RetainPtr<CFRunLoopRef> m_runLoop;190};191void create_member_init() {192  MemberInit init { adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10)), @"hello", CFRunLoopGetCurrent() };193}194 195RetainPtr<CFStringRef> cfstr() {196  return CFSTR("");197}198 199template <typename CF, typename NS>200static RetainPtr<NS> bridge_cast(RetainPtr<CF>&& ptr)201{202  return adoptNS((__bridge NSArray *)(ptr.leakRef()));203}204 205RetainPtr<CFArrayRef> create_cf_array();206RetainPtr<id> return_bridge_cast() {207  return bridge_cast<CFArrayRef, NSArray>(create_cf_array());208}209 210void mutable_copy_dictionary() {211  RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{212    @"Content-Type": @"text/html",213  }.mutableCopy);214}215 216void mutable_copy_array() {217  RetainPtr<NSMutableArray> mutableArray = adoptNS(@[218      @"foo",219  ].mutableCopy);220}221 222void string_copy(NSString *str) {223  RetainPtr<NSString> copy = adoptNS(str.copy);224}225 226void alloc_init_spi() {227  auto ptr = adoptNS([[SomeObj alloc] _init]);228}229 230void alloc_init_c_function() {231  RetainPtr ptr = adoptNS([allocSomeObj() init]);232}233 234CFArrayRef make_array() CF_RETURNS_RETAINED;235 236RetainPtr<CFArrayRef> adopt_make_array() {237  return adoptCF(make_array());238}239 240@interface SomeObject : NSObject241-(void)basic_correct;242-(void)basic_wrong;243-(NSString *)leak_string;244-(NSString *)make_string NS_RETURNS_RETAINED;245@property (nonatomic, readonly) SomeObj *obj;246@end247 248@implementation SomeObject249-(void)basic_correct {250  auto ns1 = adoptNS([SomeObj alloc]);251  auto ns2 = adoptNS([[SomeObj alloc] init]);252  RetainPtr<SomeObj> ns3 = [ns1.get() next];253  auto ns4 = adoptNS([ns3 mutableCopy]);254  auto ns5 = adoptNS([ns3 copyWithValue:3]);255  auto ns6 = retainPtr([ns3 next]);256  CFMutableArrayRef cf1 = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10));257  auto cf2 = adoptCF(SecTaskCreateFromSelf(kCFAllocatorDefault));258  auto cf3 = adoptCF(checked_cf_cast<CFArrayRef>(CFCopyArray(cf1)));259}260 261-(void)basic_wrong {262  RetainPtr<SomeObj> ns1 = [[SomeObj alloc] init];263  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}264  auto ns2 = adoptNS([ns1.get() next]);265  // expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}266  RetainPtr<CFMutableArrayRef> cf1 = CFArrayCreateMutable(kCFAllocatorDefault, 10);267  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}268  RetainPtr<CFMutableArrayRef> cf2 = adoptCF(provide_cf());269  // expected-warning@-1{{Incorrect use of adoptCF. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}270  RetainPtr<CFTypeRef> cf3 = SecTaskCreateFromSelf(kCFAllocatorDefault);271  // expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}272  CFCopyArray(cf1);273  // expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}274}275 276-(NSString *)leak_string {277  return [[NSString alloc] initWithUTF8String:"hello"];278}279 280-(NSString *)make_string {281  return [[NSString alloc] initWithUTF8String:"hello"];282}283 284-(void)local_leak_string {285  if ([[NSString alloc] initWithUTF8String:"hello"]) {286  }287}288 289-(void)make_some_obj {290  auto some_obj = adoptNS([allocSomeObj() init]);291}292 293-(void)alloc_init_bad_order {294  auto *obj = [NSObject alloc];295  auto ptr = adoptNS([obj init]);296  // expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}297}298 299-(void)alloc_init_good_order {300  auto obj = adoptNS([NSObject alloc]);301  (void)[obj init];302}303 304-(void)copy_assign_ivar {305  _obj = [allocSomeObj() init];306}307 308-(void)do_more_work:(OtherObj *)otherObj {309  [otherObj doMoreWork:[[OtherObj alloc] init]];310}311@end312