-
Notifications
You must be signed in to change notification settings - Fork 15k
[alpha.webkit.RetainPtrCtorAdoptChecker] Allow leakRef in copy methods #160986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1.
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-static-analyzer-1 Author: Ryosuke Niwa (rniwa) ChangesAllow leakRef() in the return statement of an Objective-C copy method and other methods which return +1. Full diff: https://github.com/llvm/llvm-project/pull/160986.diff 3 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
index e1f9a77f5a5ca..955b8d19a820c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
@@ -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))
diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
index 39dee1746158b..dacb713130818 100644
--- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
@@ -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;
@@ -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;
@@ -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*;
@@ -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; }
diff --git a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm
index 769901778cdf0..45705615f3196 100644
--- a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm
+++ b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm
@@ -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() {
@@ -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);
@@ -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 {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
|
Thank you! |
llvm#160986) Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1.
llvm#160986) Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1.
llvm#160986) Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1. (cherry picked from commit 103d2ca)
Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1.