[clang] [alpha.webkit.ForwardDeclChecker] Ignore unary operator when detecting a parameter (PR #160994)

Ryosuke Niwa via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 27 01:59:41 PDT 2025


https://github.com/rniwa created https://github.com/llvm/llvm-project/pull/160994

This PR updates the forward declaration checker so that unary operator & and * will be ignored for the purpose of determining if a given function argument is also a function argument of the caller / call-site.

>From bc6988f7e9dbd4880d2d3ed530847c74bf5d92af Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Sat, 27 Sep 2025 01:55:50 -0700
Subject: [PATCH] [alpha.webkit.ForwardDeclChecker] Ignore unary operator when
 detecting a parameter

This PR updates the forward declaration checker so that unary operator & and * will
be ignored for the purpose of determining if a given function argument is also a
function argument of the caller / call-site.
---
 .../Checkers/WebKit/ForwardDeclChecker.cpp    | 26 ++++++++++++++-----
 .../Checkers/WebKit/forward-decl-checker.mm   |  8 ++++++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
index d8539eaaac49f..d8a796c7847d4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
@@ -263,18 +263,30 @@ class ForwardDeclChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
   void visitCallArg(const Expr *Arg, const ParmVarDecl *Param,
                     const Decl *DeclWithIssue) const {
     auto *ArgExpr = Arg->IgnoreParenCasts();
-    if (auto *InnerCE = dyn_cast<CallExpr>(Arg)) {
-      auto *InnerCallee = InnerCE->getDirectCallee();
-      if (InnerCallee && InnerCallee->isInStdNamespace() &&
-          safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) {
-        ArgExpr = InnerCE->getArg(0);
-        if (ArgExpr)
-          ArgExpr = ArgExpr->IgnoreParenCasts();
+    while (ArgExpr) {
+      ArgExpr = ArgExpr->IgnoreParenCasts();
+      if (auto *InnerCE = dyn_cast<CallExpr>(ArgExpr)) {
+        auto *InnerCallee = InnerCE->getDirectCallee();
+        if (InnerCallee && InnerCallee->isInStdNamespace() &&
+            safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) {
+          ArgExpr = InnerCE->getArg(0);
+          continue;
+        }
+      }
+      if (auto *UO = dyn_cast<UnaryOperator>(ArgExpr)) {
+        auto OpCode = UO->getOpcode();
+        if (OpCode == UO_Deref || OpCode == UO_AddrOf) {
+          ArgExpr = UO->getSubExpr();
+          continue;
+        }
       }
+      break;
     }
+
     if (isNullPtr(ArgExpr) || isa<IntegerLiteral>(ArgExpr) ||
         isa<CXXDefaultArgExpr>(ArgExpr))
       return;
+
     if (auto *DRE = dyn_cast<DeclRefExpr>(ArgExpr)) {
       if (auto *ValDecl = DRE->getDecl()) {
         if (isa<ParmVarDecl>(ValDecl))
diff --git a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
index 104b555c1c41d..50411ea9026b5 100644
--- a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
+++ b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
@@ -11,6 +11,8 @@
 
 Obj* provide_obj_ptr();
 void receive_obj_ptr(Obj* p = nullptr);
+void receive_obj_ref(Obj&);
+void receive_obj_rref(Obj&&);
 sqlite3* open_db();
 void close_db(sqlite3*);
 
@@ -38,6 +40,12 @@
   return obj;
 }
 
+void opaque_call_arg(Obj* obj, Obj&& otherObj) {
+  receive_obj_ref(*obj);
+  receive_obj_ptr(&*obj);
+  receive_obj_rref(std::move(otherObj));
+}
+
 Obj&& provide_obj_rval();
 void receive_obj_rval(Obj&& p);
 



More information about the cfe-commits mailing list