Author: Ryosuke Niwa Date: 2025-10-01T15:01:44-07:00 New Revision: 103d2cae80160ebe79a91e4b4239140e2cd52283
URL: https://github.com/llvm/llvm-project/commit/103d2cae80160ebe79a91e4b4239140e2cd52283 DIFF: https://github.com/llvm/llvm-project/commit/103d2cae80160ebe79a91e4b4239140e2cd52283.diff LOG: [alpha.webkit.RetainPtrCtorAdoptChecker] Allow leakRef in copy methods (#160986) Allow leakRef() in the return statement of an Objective-C copy method and other methods which return +1. Added: Modified: clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp clang/test/Analysis/Checkers/WebKit/objc-mock-types.h clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm Removed: ################################################################################ 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 { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
