CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
367 lines
11 KiB
Plaintext
367 lines
11 KiB
Plaintext
// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
|
|
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.RetainPtrCtorAdoptChecker -verify %s
|
|
|
|
#include "objc-mock-types.h"
|
|
|
|
CFTypeRef CFCopyArray(CFArrayRef);
|
|
void* CreateCopy();
|
|
|
|
void basic_correct() {
|
|
auto ns1 = adoptNS([SomeObj alloc]);
|
|
auto ns2 = adoptNS([[SomeObj alloc] init]);
|
|
RetainPtr<SomeObj> ns3 = [ns1.get() next];
|
|
auto ns4 = adoptNS([ns3 mutableCopy]);
|
|
auto ns5 = adoptNS([ns3 copyWithValue:3]);
|
|
auto ns6 = retainPtr([ns3 next]);
|
|
auto ns7 = retainPtr((SomeObj *)0);
|
|
auto ns8 = adoptNS(nil);
|
|
auto ns9 = adoptNSNullable([[SomeObj alloc] init]);
|
|
CFMutableArrayRef cf1 = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10));
|
|
auto cf2 = adoptCF(SecTaskCreateFromSelf(kCFAllocatorDefault));
|
|
auto cf3 = adoptCF(checked_cf_cast<CFArrayRef>(CFCopyArray(cf1)));
|
|
auto cf4 = adoptCFNullable(CFArrayCreateMutable(kCFAllocatorDefault, 10));
|
|
CreateCopy();
|
|
}
|
|
|
|
CFMutableArrayRef provide_cf();
|
|
|
|
void basic_wrong() {
|
|
RetainPtr<SomeObj> ns1 = [[SomeObj alloc] init];
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
auto ns2 = adoptNS([ns1.get() next]);
|
|
// expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
auto ns3 = adoptNSNullable([ns1.get() next]);
|
|
// expected-warning@-1{{Incorrect use of adoptNSNullable. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFMutableArrayRef> cf1 = CFArrayCreateMutable(kCFAllocatorDefault, 10);
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFMutableArrayRef> cf2 = adoptCF(provide_cf());
|
|
// expected-warning@-1{{Incorrect use of adoptCF. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFTypeRef> cf3 = SecTaskCreateFromSelf(kCFAllocatorDefault);
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
CFCopyArray(cf1);
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFMutableArrayRef> cf4 = adoptCFNullable(provide_cf());
|
|
// expected-warning@-1{{Incorrect use of adoptCFNullable. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
|
|
void basic_correct_arc() {
|
|
auto *obj = [[SomeObj alloc] init];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
[obj doWork];
|
|
}
|
|
|
|
@implementation SomeObj {
|
|
NSNumber *_number;
|
|
SomeObj *_next;
|
|
SomeObj *_other;
|
|
}
|
|
|
|
- (instancetype)_init {
|
|
self = [super init];
|
|
_number = nil;
|
|
_next = nil;
|
|
_other = nil;
|
|
return self;
|
|
}
|
|
|
|
- (SomeObj *)mutableCopy {
|
|
auto *copy = [[SomeObj alloc] init];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
[copy setValue:_number];
|
|
[copy setNext:_next];
|
|
[copy setOther:_other];
|
|
return copy;
|
|
}
|
|
|
|
- (SomeObj *)copyWithValue:(int)value {
|
|
auto *copy = [[SomeObj alloc] init];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
[copy setValue:_number];
|
|
[copy setNext:_next];
|
|
[copy setOther:_other];
|
|
return copy;
|
|
}
|
|
|
|
- (void)copy:(id)sender {
|
|
}
|
|
|
|
- (void)doWork {
|
|
_number = [[NSNumber alloc] initWithInt:5];
|
|
}
|
|
|
|
- (SomeObj *)other {
|
|
return _other;
|
|
}
|
|
|
|
- (void)setOther:(SomeObj *)obj {
|
|
_other = obj;
|
|
}
|
|
|
|
- (SomeObj *)next {
|
|
return _next;
|
|
}
|
|
|
|
- (void)setNext:(SomeObj *)obj {
|
|
_next = obj;
|
|
}
|
|
|
|
- (int)value {
|
|
return [_number intValue];
|
|
}
|
|
|
|
- (void)setValue:value {
|
|
_number = value;
|
|
}
|
|
|
|
- (id)copyWithZone:(NSZone *)zone {
|
|
auto copy = adoptNS([(SomeObj *)[SomeObj allocWithZone:zone] init]);
|
|
[copy setValue:_number];
|
|
[copy setNext:_next];
|
|
[copy setOther:_other];
|
|
return copy.leakRef();
|
|
}
|
|
|
|
@end;
|
|
|
|
@interface SubObj : SomeObj
|
|
@end
|
|
|
|
@implementation SubObj
|
|
|
|
- (void)copy:(id)sender {
|
|
[super copy:sender];
|
|
}
|
|
|
|
@end
|
|
|
|
RetainPtr<CVPixelBufferRef> cf_out_argument() {
|
|
auto surface = adoptCF(IOSurfaceCreate(nullptr));
|
|
CVPixelBufferRef rawBuffer = nullptr;
|
|
auto status = CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, surface.get(), nullptr, &rawBuffer);
|
|
return adoptCF(rawBuffer);
|
|
}
|
|
|
|
RetainPtr<SomeObj> return_nil() {
|
|
return nil;
|
|
}
|
|
|
|
RetainPtr<SomeObj> return_nullptr() {
|
|
return nullptr;
|
|
}
|
|
|
|
RetainPtr<SomeObj> return_retainptr() {
|
|
RetainPtr<SomeObj> foo;
|
|
return foo;
|
|
}
|
|
|
|
CFTypeRef CopyValueForSomething();
|
|
|
|
void cast_retainptr() {
|
|
RetainPtr<NSObject> foo;
|
|
RetainPtr<SomeObj> bar = static_cast<SomeObj*>(foo);
|
|
|
|
auto baz = adoptCF(CopyValueForSomething()).get();
|
|
RetainPtr<CFArrayRef> v = static_cast<CFArrayRef>(baz);
|
|
}
|
|
|
|
CFTypeRef CopyWrapper() {
|
|
return CopyValueForSomething();
|
|
}
|
|
|
|
CFTypeRef LeakWrapper() {
|
|
return CopyValueForSomething();
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
|
|
NSArray *makeArray() NS_RETURNS_RETAINED {
|
|
return (__bridge NSArray *)CFArrayCreateMutable(kCFAllocatorDefault, 10);
|
|
}
|
|
|
|
extern Class (*getNSArrayClass)();
|
|
NSArray *allocArrayInstance() NS_RETURNS_RETAINED {
|
|
return adoptNS([[getNSArrayClass() alloc] init]).leakRef();
|
|
}
|
|
|
|
extern int (*GetObj)(CF_RETURNS_RETAINED CFTypeRef* objOut);
|
|
RetainPtr<CFTypeRef> getObject() {
|
|
CFTypeRef obj = nullptr;
|
|
if (GetObj(&obj))
|
|
return nullptr;
|
|
return adoptCF(obj);
|
|
}
|
|
|
|
CFArrayRef CreateSingleArray(CFStringRef);
|
|
CFArrayRef CreateSingleArray(CFDictionaryRef);
|
|
CFArrayRef CreateSingleArray(CFArrayRef);
|
|
template <typename ElementType>
|
|
static RetainPtr<CFArrayRef> makeArrayWithSingleEntry(ElementType arg) {
|
|
return adoptCF(CreateSingleArray(arg));
|
|
}
|
|
|
|
void callMakeArayWithSingleEntry() {
|
|
auto dictionary = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, nullptr, nullptr, 0));
|
|
makeArrayWithSingleEntry(dictionary.get());
|
|
}
|
|
|
|
SomeObj* allocSomeObj() CF_RETURNS_RETAINED;
|
|
|
|
void adopt_retainptr() {
|
|
RetainPtr<NSObject> foo = adoptNS([[SomeObj alloc] init]);
|
|
auto bar = adoptNS([allocSomeObj() init]);
|
|
}
|
|
|
|
CFTypeRef make_cf_obj() CF_RETURNS_RETAINED {
|
|
return CFArrayCreateMutable(kCFAllocatorDefault, 1);
|
|
}
|
|
|
|
void get_cf_obj(CFTypeRef* CF_RETURNS_RETAINED result) {
|
|
*result = CFArrayCreateMutable(kCFAllocatorDefault, 1);
|
|
}
|
|
|
|
RetainPtr<CFArrayRef> return_arg(CFArrayRef arg) {
|
|
return arg;
|
|
}
|
|
|
|
class MemberInit {
|
|
public:
|
|
MemberInit(RetainPtr<CFMutableArrayRef>&& array, NSString *str, CFRunLoopRef runLoop)
|
|
: m_array(array)
|
|
, m_str(str)
|
|
, m_runLoop(runLoop)
|
|
{ }
|
|
|
|
private:
|
|
RetainPtr<CFMutableArrayRef> m_array;
|
|
RetainPtr<NSString> m_str;
|
|
RetainPtr<CFRunLoopRef> m_runLoop;
|
|
};
|
|
void create_member_init() {
|
|
MemberInit init { adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10)), @"hello", CFRunLoopGetCurrent() };
|
|
}
|
|
|
|
RetainPtr<CFStringRef> cfstr() {
|
|
return CFSTR("");
|
|
}
|
|
|
|
template <typename CF, typename NS>
|
|
static RetainPtr<NS> bridge_cast(RetainPtr<CF>&& ptr)
|
|
{
|
|
return adoptNS((__bridge NSArray *)(ptr.leakRef()));
|
|
}
|
|
|
|
RetainPtr<CFArrayRef> create_cf_array();
|
|
RetainPtr<id> return_bridge_cast() {
|
|
return bridge_cast<CFArrayRef, NSArray>(create_cf_array());
|
|
}
|
|
|
|
void mutable_copy_dictionary() {
|
|
RetainPtr<NSMutableDictionary> mutableDictionary = adoptNS(@{
|
|
@"Content-Type": @"text/html",
|
|
}.mutableCopy);
|
|
}
|
|
|
|
void mutable_copy_array() {
|
|
RetainPtr<NSMutableArray> mutableArray = adoptNS(@[
|
|
@"foo",
|
|
].mutableCopy);
|
|
}
|
|
|
|
void string_copy(NSString *str) {
|
|
RetainPtr<NSString> copy = adoptNS(str.copy);
|
|
}
|
|
|
|
void alloc_init_spi() {
|
|
auto ptr = adoptNS([[SomeObj alloc] _init]);
|
|
}
|
|
|
|
void alloc_init_c_function() {
|
|
RetainPtr ptr = adoptNS([allocSomeObj() init]);
|
|
}
|
|
|
|
void alloc_init_autorelease() {
|
|
[[[SomeObj alloc] init] autorelease];
|
|
}
|
|
|
|
CFArrayRef make_array() CF_RETURNS_RETAINED;
|
|
|
|
RetainPtr<CFArrayRef> adopt_make_array() {
|
|
return adoptCF(make_array());
|
|
}
|
|
|
|
@interface SomeObject : NSObject
|
|
-(void)basic_correct;
|
|
-(void)basic_wrong;
|
|
-(NSString *)leak_string;
|
|
-(NSString *)make_string NS_RETURNS_RETAINED;
|
|
@property (nonatomic, readonly) SomeObj *obj;
|
|
@end
|
|
|
|
@implementation SomeObject
|
|
-(void)basic_correct {
|
|
auto ns1 = adoptNS([SomeObj alloc]);
|
|
auto ns2 = adoptNS([[SomeObj alloc] init]);
|
|
RetainPtr<SomeObj> ns3 = [ns1.get() next];
|
|
auto ns4 = adoptNS([ns3 mutableCopy]);
|
|
auto ns5 = adoptNS([ns3 copyWithValue:3]);
|
|
auto ns6 = retainPtr([ns3 next]);
|
|
CFMutableArrayRef cf1 = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, 10));
|
|
auto cf2 = adoptCF(SecTaskCreateFromSelf(kCFAllocatorDefault));
|
|
auto cf3 = adoptCF(checked_cf_cast<CFArrayRef>(CFCopyArray(cf1)));
|
|
}
|
|
|
|
-(void)basic_wrong {
|
|
RetainPtr<SomeObj> ns1 = [[SomeObj alloc] init];
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
auto ns2 = adoptNS([ns1.get() next]);
|
|
// expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFMutableArrayRef> cf1 = CFArrayCreateMutable(kCFAllocatorDefault, 10);
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFMutableArrayRef> cf2 = adoptCF(provide_cf());
|
|
// expected-warning@-1{{Incorrect use of adoptCF. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
RetainPtr<CFTypeRef> cf3 = SecTaskCreateFromSelf(kCFAllocatorDefault);
|
|
// expected-warning@-1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
CFCopyArray(cf1);
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
|
|
-(NSString *)leak_string {
|
|
return [[NSString alloc] initWithUTF8String:"hello"];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
|
|
-(NSString *)make_string {
|
|
return adoptNS([[NSString alloc] initWithUTF8String:"hello"]).leakRef();
|
|
}
|
|
|
|
-(void)local_leak_string {
|
|
if ([[NSString alloc] initWithUTF8String:"hello"]) {
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
}
|
|
|
|
-(void)make_some_obj {
|
|
auto some_obj = adoptNS([allocSomeObj() init]);
|
|
}
|
|
|
|
-(void)alloc_init_bad_order {
|
|
auto *obj = [NSObject alloc];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
auto ptr = adoptNS([obj init]);
|
|
// expected-warning@-1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
|
|
-(void)alloc_init_good_order {
|
|
auto obj = adoptNS([NSObject alloc]);
|
|
(void)[obj init];
|
|
}
|
|
|
|
-(void)copy_assign_ivar {
|
|
_obj = [allocSomeObj() init];
|
|
}
|
|
|
|
-(void)do_more_work:(OtherObj *)otherObj {
|
|
[otherObj doMoreWork:[[OtherObj alloc] init]];
|
|
// expected-warning@-1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
|
|
}
|
|
@end
|