[clang] ec06755 - Add the support for adoptCFNullable/adoptNSNullable (#194539)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 08:48:22 PDT 2026
Author: Ryosuke Niwa
Date: 2026-04-28T08:48:16-07:00
New Revision: ec0675591f0dd5a4bfed477b0d5e25aa404d7e0f
URL: https://github.com/llvm/llvm-project/commit/ec0675591f0dd5a4bfed477b0d5e25aa404d7e0f
DIFF: https://github.com/llvm/llvm-project/commit/ec0675591f0dd5a4bfed477b0d5e25aa404d7e0f.diff
LOG: Add the support for adoptCFNullable/adoptNSNullable (#194539)
These are two new "adopt" functions to be introduced in WebKit.
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
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-arc.mm
clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use.mm
clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index d239ed4c8a5ae..b8c8359c22773 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -175,7 +175,8 @@ bool isCtorOfCheckedPtr(const clang::FunctionDecl *F) {
bool isCtorOfRetainPtrOrOSPtr(const clang::FunctionDecl *F) {
const std::string &FunctionName = safeGetName(F);
return FunctionName == "RetainPtr" || FunctionName == "adoptNS" ||
- FunctionName == "adoptCF" || FunctionName == "retainPtr" ||
+ FunctionName == "adoptNSNullable" || FunctionName == "adoptCF" ||
+ FunctionName == "adoptCFNullable" || FunctionName == "retainPtr" ||
FunctionName == "RetainPtrArc" || FunctionName == "adoptNSArc" ||
FunctionName == "adoptOSObject" || FunctionName == "adoptOSObjectArc";
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
index 2af9067f8f808..afa9fc7b1c4a4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
@@ -122,11 +122,13 @@ class RetainPtrCtorAdoptChecker
bool isAdoptFnName(const std::string &Name) const {
return isAdoptNS(Name) || Name == "adoptCF" || Name == "adoptCFArc" ||
+ Name == "adoptCFNullable" || Name == "adoptCFNullableArc" ||
Name == "adoptOSObject" || Name == "adoptOSObjectArc";
}
bool isAdoptNS(const std::string &Name) const {
- return Name == "adoptNS" || Name == "adoptNSArc";
+ return Name == "adoptNS" || Name == "adoptNSArc" ||
+ Name == "adoptNSNullable" || Name == "adoptNSNullableArc";
}
void visitCallExpr(const CallExpr *CE, const Decl *DeclWithIssue) const {
diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
index 124821a8ded55..503d11bea3089 100644
--- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
@@ -265,7 +265,9 @@ void WTFCrash(void);
template<typename T> class RetainPtr;
template<typename T> RetainPtr<T> adoptNS(T*);
+template<typename T> RetainPtr<T> adoptNSNullable(T*);
template<typename T> RetainPtr<T> adoptCF(T);
+template<typename T> RetainPtr<T> adoptCFNullable(T);
template <typename T, typename S> T *downcast(S *t) { return static_cast<T*>(t); }
@@ -367,7 +369,9 @@ template <typename T> struct RetainPtr {
CFTypeRef toCFTypeRef(const void* ptr) { return (CFTypeRef)ptr; }
template <typename U> friend RetainPtr<U> adoptNS(U*);
+ template <typename U> friend RetainPtr<U> adoptNSNullable(U*);
template <typename U> friend RetainPtr<U> adoptCF(U);
+ template <typename U> friend RetainPtr<U> adoptCFNullable(U);
enum AdoptTag { Adopt };
RetainPtr(PtrType t, AdoptTag) : t(t) { }
@@ -395,11 +399,25 @@ RetainPtr<T> adoptNS(T* t) {
#endif
}
+template <typename T>
+RetainPtr<T> adoptNSNullable(T* t) {
+#if __has_feature(objc_arc)
+ return t;
+#else
+ return RetainPtr<T>(t, RetainPtr<T>::Adopt);
+#endif
+}
+
template <typename T>
RetainPtr<T> adoptCF(T t) {
return RetainPtr<T>(t, RetainPtr<T>::Adopt);
}
+template <typename T>
+RetainPtr<T> adoptCFNullable(T t) {
+ return RetainPtr<T>(t, RetainPtr<T>::Adopt);
+}
+
template<typename T> inline RetainPtr<T> retainPtr(T ptr)
{
return ptr;
@@ -681,7 +699,9 @@ WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFDictionary, CFMutableDictionary);
using WTF::RetainPtr;
using WTF::adoptNS;
+using WTF::adoptNSNullable;
using WTF::adoptCF;
+using WTF::adoptCFNullable;
using WTF::retainPtr;
using WTF::OSObjectPtr;
using WTF::adoptOSObject;
diff --git a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm
index 79ea95b088167..135fe651a9f16 100644
--- a/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/retain-ptr-ctor-adopt-use-arc.mm
@@ -12,9 +12,11 @@ void basic_correct() {
auto ns4 = adoptNS([ns3 mutableCopy]);
auto ns5 = adoptNS([ns3 copyWithValue:3]);
auto ns6 = retainPtr([ns3 next]);
+ auto ns7 = 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));
}
CFMutableArrayRef provide_cf();
@@ -24,6 +26,8 @@ void basic_wrong() {
// expected-warning at -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 at -1{{Incorrect use of adoptNS. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}
+ auto ns3 = adoptNSNullable([ns1.get() next]);
+ // expected-warning at -1{{Incorrect use of adoptNSNullable. 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 at -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());
@@ -32,6 +36,8 @@ void basic_wrong() {
// expected-warning at -1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
CFCopyArray(cf1);
// expected-warning at -1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
+ RetainPtr<CFMutableArrayRef> cf4 = adoptCFNullable(provide_cf());
+ // expected-warning at -1{{Incorrect use of adoptCFNullable. The argument is +0 and results in an use-after-free when ARC is disabled [alpha.webkit.RetainPtrCtorAdoptChecker]}}
}
void basic_correct_arc() {
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 20f951b27a149..c337752d6bd21 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
@@ -15,9 +15,11 @@ void basic_correct() {
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();
}
@@ -28,6 +30,8 @@ void basic_wrong() {
// expected-warning at -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 at -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 at -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 at -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());
@@ -36,6 +40,8 @@ void basic_wrong() {
// expected-warning at -1{{Incorrect use of RetainPtr constructor. The argument is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
CFCopyArray(cf1);
// expected-warning at -1{{The return value is +1 and results in a memory leak [alpha.webkit.RetainPtrCtorAdoptChecker]}}
+ RetainPtr<CFMutableArrayRef> cf4 = adoptCFNullable(provide_cf());
+ // expected-warning at -1{{Incorrect use of adoptCFNullable. The argument is +0 and results in an use-after-free [alpha.webkit.RetainPtrCtorAdoptChecker]}}
}
void basic_correct_arc() {
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index cfc214fae33e5..add9144744db4 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -385,7 +385,9 @@ void os_ptr() {
namespace call_with_adopt_ref {
void foo() {
[adoptNS(provide()).get() doWork];
+ [adoptNSNullable(provide()).get() doWork];
CFArrayAppendValue(adoptCF(provide_cf()).get(), nullptr);
+ CFArrayAppendValue(adoptCFNullable(provide_cf()).get(), nullptr);
consume_dispatch(adoptOSObject(provide_dispatch()).get());
}
}
More information about the cfe-commits
mailing list