https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/161633
>From 35ae9ac455dac75db1745984dc740cf276a9dcc8 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Wed, 1 Oct 2025 23:41:54 -0700 Subject: [PATCH 1/2] [alpha.webkit.RetainPtrCtorAdoptChecker] Don't treat assignment to an +1 out argument as a leak Make RetainPtrCtorAdoptChecker recognize an assignment to an +1 out argument so that it won't emit a memory leak warning. --- .../WebKit/RetainPtrCtorAdoptChecker.cpp | 30 ++++++++++++++----- .../WebKit/retain-ptr-ctor-adopt-use.mm | 8 +++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp index e1f9a77f5a5ca..7440352d8482d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp @@ -355,14 +355,30 @@ class RetainPtrCtorAdoptChecker void visitBinaryOperator(const BinaryOperator *BO) const { if (!BO->isAssignmentOp()) return; - if (!isa<ObjCIvarRefExpr>(BO->getLHS())) - return; + auto *LHS = BO->getLHS(); auto *RHS = BO->getRHS()->IgnoreParenCasts(); - const Expr *Inner = nullptr; - if (isAllocInit(RHS, &Inner)) { - CreateOrCopyFnCall.insert(RHS); - if (Inner) - CreateOrCopyFnCall.insert(Inner); + if (isa<ObjCIvarRefExpr>(LHS)) { + const Expr *Inner = nullptr; + if (isAllocInit(RHS, &Inner)) { + CreateOrCopyFnCall.insert(RHS); + if (Inner) + CreateOrCopyFnCall.insert(Inner); + } + return; + } else if (auto *UO = dyn_cast<UnaryOperator>(LHS)) { + auto OpCode = UO->getOpcode(); + if (OpCode == UO_Deref) { + if (auto *DerefTarget = UO->getSubExpr()) { + DerefTarget = DerefTarget->IgnoreParenCasts(); + auto *DRE = dyn_cast<DeclRefExpr>(DerefTarget); + if (auto *Decl = DRE->getDecl()) { + if (!isa<ParmVarDecl>(Decl) || !isCreateOrCopy(RHS)) + return; + if (Decl->hasAttr<CFReturnsRetainedAttr>()) + CreateOrCopyFnCall.insert(RHS); + } + } + } } } 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..3b0f19404097b 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 @@ -182,6 +182,14 @@ void adopt_retainptr() { auto bar = adoptNS([allocSomeObj() init]); } +CFTypeRef make_cf_obj() CF_RETURNS_RETAINED { + return CFArrayCreateMutable(kCFAllocatorDefault, 1); +} + +void get_cf_obj(CFTypeRef* CF_RETURNS_RETAINED result) { + *result = CFArrayCreateMutable(kCFAllocatorDefault, 1); +} + RetainPtr<CFArrayRef> return_arg(CFArrayRef arg) { return arg; } >From e7bff0869f8981eef6ae1fb4b3f3985e1ce9aed9 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Mon, 8 Dec 2025 16:53:52 -0800 Subject: [PATCH 2/2] Address the review comment. Also turn nested ifs to early exits. --- .../WebKit/RetainPtrCtorAdoptChecker.cpp | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp index 7440352d8482d..d98df2117739e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp @@ -365,21 +365,27 @@ class RetainPtrCtorAdoptChecker CreateOrCopyFnCall.insert(Inner); } return; - } else if (auto *UO = dyn_cast<UnaryOperator>(LHS)) { - auto OpCode = UO->getOpcode(); - if (OpCode == UO_Deref) { - if (auto *DerefTarget = UO->getSubExpr()) { - DerefTarget = DerefTarget->IgnoreParenCasts(); - auto *DRE = dyn_cast<DeclRefExpr>(DerefTarget); - if (auto *Decl = DRE->getDecl()) { - if (!isa<ParmVarDecl>(Decl) || !isCreateOrCopy(RHS)) - return; - if (Decl->hasAttr<CFReturnsRetainedAttr>()) - CreateOrCopyFnCall.insert(RHS); - } - } - } } + auto *UO = dyn_cast<UnaryOperator>(LHS); + if (!UO) + return; + auto OpCode = UO->getOpcode(); + if (OpCode != UO_Deref) + return; + auto *DerefTarget = UO->getSubExpr(); + if (!DerefTarget) + return; + DerefTarget = DerefTarget->IgnoreParenCasts(); + auto *DRE = dyn_cast<DeclRefExpr>(DerefTarget); + if (!DRE) + return; + auto *Decl = DRE->getDecl(); + if (!Decl) + return; + if (!isa<ParmVarDecl>(Decl) || !isCreateOrCopy(RHS)) + return; + if (Decl->hasAttr<CFReturnsRetainedAttr>()) + CreateOrCopyFnCall.insert(RHS); } void visitReturnStmt(const ReturnStmt *RS, const Decl *DeclWithIssue) const { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
