[clang] [WebKit Checkers] Allow operator T&() in a const member function (PR #126470)

Ryosuke Niwa via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 9 21:53:31 PST 2025


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

Allow operator T&() in a member function which returns a const member variable.

In particular, this will allow UniqueRef::operator T&() and Ref::operator T&() to be treated as a safe pointer origin when they're called on a const member.

>From b795148061279951c9fa97421d07f6bf812eb302 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Sun, 9 Feb 2025 21:48:15 -0800
Subject: [PATCH] [WebKit Checkers] Allow operator T&() in a const member
 function

Allow operator T&() in a member function which returns a const member variable.

In particular, this will allow UniqueRef::operator T&() and Ref::operator T&()
to be treated as a safe pointer origin when they're called on a const member.
---
 clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp     | 8 ++++----
 .../Checkers/WebKit/call-args-counted-const-member.cpp    | 4 ++++
 clang/test/Analysis/Checkers/WebKit/mock-types.h          | 1 +
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index abf5d3ec193a41a..9eb0c8ed5c8419f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -154,10 +154,10 @@ bool isConstOwnerPtrMemberExpr(const clang::Expr *E) {
   if (auto *MCE = dyn_cast<CXXMemberCallExpr>(E)) {
     if (auto *Callee = MCE->getDirectCallee()) {
       auto Name = safeGetName(Callee);
-      if (Name == "get" || Name == "ptr") {
-        auto *ThisArg = MCE->getImplicitObjectArgument();
-        E = ThisArg;
-      }
+      if (Name == "get" || Name == "ptr")
+        E = MCE->getImplicitObjectArgument();
+      if (auto *CD = dyn_cast<CXXConversionDecl>(Callee))
+        E = MCE->getImplicitObjectArgument();
     }
   } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
     if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1)
diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp
index 215238a7fcf0712..8da415a818a8296 100644
--- a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp
@@ -31,6 +31,7 @@ class Foo {
 public:
   Foo();
   void bar();
+  RefCountable& obj1() const { return m_obj1; }
 
 private:
   const Ref<RefCountable> m_obj1;
@@ -41,6 +42,7 @@ void Foo::bar() {
   m_obj1->method();
   m_obj2->method();
   // expected-warning at -1{{Call argument for 'this' parameter is uncounted and unsafe}}
+  obj1().method();
 }
 
 } // namespace call_args_const_ref_member
@@ -100,6 +102,7 @@ class Foo {
 public:
   Foo();
   void bar();
+  RefCountable& obj1() { return m_obj1; }
 
 private:
   const UniqueRef<RefCountable> m_obj1;
@@ -110,6 +113,7 @@ void Foo::bar() {
   m_obj1->method();
   m_obj2->method();
   // expected-warning at -1{{Call argument for 'this' parameter is uncounted and unsafe}}
+  obj1().method();
 }
 
 } // namespace call_args_const_unique_ref
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h
index 85397c2d259516d..a1f0cc8b046b995 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h
@@ -289,6 +289,7 @@ class UniqueRef {
     u.t = nullptr;
   }
   T &get() const { return *t; }
+  operator T&() const { return *t; }
   T *operator->() const { return t; }
   UniqueRef &operator=(T &) { return *this; }
 };



More information about the cfe-commits mailing list