blob: 45db0506ae5f2ef347c355245d546dc7bc731aa5 [file] [log] [blame]
// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.RetainPtrCtorAdoptChecker -fobjc-arc -verify %s
#include "objc-mock-types.h"
CFTypeRef CFCopyArray(CFArrayRef);
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)));
}
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 when ARC is disabled [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 when ARC is disabled [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<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_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);
}
SomeObj* allocSomeObj();
void adopt_retainptr() {
RetainPtr<NSObject> foo = adoptNS([[SomeObj alloc] init]);
auto bar = adoptNS([allocSomeObj() init]);
}
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);
}