[clang] b64ed9d - [WebKit checkers] Recognize NS_RETURNS_RETAINED and CF_RETURNS_RETAINED. (#157629)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 11 13:32:55 PDT 2025
Author: Ryosuke Niwa
Date: 2025-09-11T13:32:51-07:00
New Revision: b64ed9d79ebc4887d7452f5fa4d08cfa6640f8ab
URL: https://github.com/llvm/llvm-project/commit/b64ed9d79ebc4887d7452f5fa4d08cfa6640f8ab
DIFF: https://github.com/llvm/llvm-project/commit/b64ed9d79ebc4887d7452f5fa4d08cfa6640f8ab.diff
LOG: [WebKit checkers] Recognize NS_RETURNS_RETAINED and CF_RETURNS_RETAINED. (#157629)
This PR adds the support for treating a function return value to be safe
if the function is annotated with NS_RETURNS_RETAINED or
CF_RETURNS_RETAINED.
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index 9a7f5b71cae71..3fc10385885a3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -91,6 +91,13 @@ bool tryToFindPtrOrigin(
continue;
}
if (auto *call = dyn_cast<CallExpr>(E)) {
+ if (auto *Callee = call->getCalleeDecl()) {
+ if (Callee->hasAttr<CFReturnsRetainedAttr>() ||
+ Callee->hasAttr<NSReturnsRetainedAttr>()) {
+ return callback(E, true);
+ }
+ }
+
if (auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
if (auto *decl = memberCall->getMethodDecl()) {
std::optional<bool> IsGetterOfRefCt = isGetterOfSafePtr(decl);
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index 3feecd930f109..f39822ee2a8c6 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -438,6 +438,32 @@ void use_const_local() {
} // namespace const_global
+namespace ns_retained_return_value {
+
+NSString *provideNS() NS_RETURNS_RETAINED;
+CFDictionaryRef provideCF() CF_RETURNS_RETAINED;
+void consumeNS(NSString *);
+void consumeCF(CFDictionaryRef);
+
+void foo() {
+ consumeNS(provideNS());
+ consumeCF(provideCF());
+}
+
+struct Base {
+ NSString *provideStr() NS_RETURNS_RETAINED;
+};
+
+struct Derived : Base {
+ void consumeStr(NSString *);
+
+ void foo() {
+ consumeStr(provideStr());
+ }
+};
+
+} // namespace ns_retained_return_value
+
@interface TestObject : NSObject
- (void)doWork:(NSString *)msg, ...;
- (void)doWorkOnSelf;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
index 10f7c9acb7a3c..0ad8f707e254c 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
@@ -408,6 +408,21 @@ void use_const_local() {
} // namespace const_global
+namespace ns_retained_return_value {
+
+NSString *provideNS() NS_RETURNS_RETAINED;
+CFDictionaryRef provideCF() CF_RETURNS_RETAINED;
+void consumeNS(NSString *);
+void consumeCF(CFDictionaryRef);
+
+unsigned foo() {
+ auto *string = provideNS();
+ auto *dictionary = provideCF();
+ return string.length + CFDictionaryGetCount(dictionary);
+}
+
+} // namespace ns_retained_return_value
+
bool doMoreWorkOpaque(OtherObj*);
SomeObj* provide();
More information about the cfe-commits
mailing list