brintos

brintos / llvm-project-archived public Read only

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