Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ class RetainPtrCtorAdoptChecker
if (RTC.isUnretained(RetValue->getType()))
return;
}
if (retainsRet && *retainsRet) {
CreateOrCopyFnCall.insert(RetValue);
return;
}
if (auto *CE = dyn_cast<CallExpr>(RetValue)) {
auto *Callee = CE->getDirectCallee();
if (!Callee || !isCreateOrCopyFunction(Callee))
Expand Down
36 changes: 35 additions & 1 deletion clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ template<typename T> typename remove_reference<T>::type&& move(T&& t);

#endif

namespace std {

template <bool, typename U = void> struct enable_if {
};

template <typename T> struct enable_if<true, T> {
using type = T;
};

template <bool value, class T = void>
using enable_if_t = typename enable_if<value, T>::type;

}

@class NSString;
@class NSArray;
@class NSMutableArray;
Expand Down Expand Up @@ -100,6 +114,7 @@ id CFBridgingRelease(CFTypeRef X) {
__attribute__((objc_root_class))
@interface NSObject
+ (instancetype) alloc;
+ (instancetype) allocWithZone:(NSZone *)zone;
+ (Class) class;
+ (Class) superclass;
- (instancetype) init;
Expand Down Expand Up @@ -232,6 +247,14 @@ template <typename T> struct RemovePointer<T*> {
typedef T Type;
};

template <typename T> struct IsPointer {
static constexpr bool value = false;
};

template <typename T> struct IsPointer<T*> {
static constexpr bool value = true;
};

template <typename T> struct RetainPtr {
using ValueType = typename RemovePointer<T>::Type;
using PtrType = ValueType*;
Expand Down Expand Up @@ -285,12 +308,23 @@ template <typename T> struct RetainPtr {
PtrType operator->() const { return t; }
T &operator*() const { return *t; }
RetainPtr &operator=(PtrType t);
PtrType leakRef()

template <typename U = PtrType>
std::enable_if_t<IsPointer<U>::value, U> leakRef() CF_RETURNS_RETAINED
{
PtrType s = t;
t = nullptr;
return s;
}

template <typename U = PtrType>
std::enable_if_t<!IsPointer<U>::value, U> leakRef() NS_RETURNS_RETAINED
{
PtrType s = t;
t = nullptr;
return s;
}

operator PtrType() const { return t; }
operator bool() const { return t; }

Expand Down
12 changes: 10 additions & 2 deletions clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ - (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;

RetainPtr<CVPixelBufferRef> cf_out_argument() {
Expand Down Expand Up @@ -151,7 +159,7 @@ CFTypeRef LeakWrapper() {

extern Class (*getNSArrayClass)();
NSArray *allocArrayInstance() NS_RETURNS_RETAINED {
return [[getNSArrayClass() alloc] init];
return adoptNS([[getNSArrayClass() alloc] init]).leakRef();
}

extern int (*GetObj)(CF_RETURNS_RETAINED CFTypeRef* objOut);
Expand Down Expand Up @@ -294,7 +302,7 @@ -(NSString *)leak_string {
}

-(NSString *)make_string {
return [[NSString alloc] initWithUTF8String:"hello"];
return adoptNS([[NSString alloc] initWithUTF8String:"hello"]).leakRef();
}

-(void)local_leak_string {
Expand Down