Skip to content

[WebKit checkers] Treat passing of a member variable which is capable of CheckedPtr as safe. #142485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

rniwa
Copy link
Contributor

@rniwa rniwa commented Jun 2, 2025

It's safe for a member function of a class or struct to call a function or allocate a local variable with a pointer or a reference to a member variable since "this" pointer, and therefore all its members, will be kept alive by its caller so recognize as such.

… of CheckedPtr as safe.

It's safe for a member function of a class or struct to call a function or allocate a local variable
with a pointer or a reference to a member variable since "this" pointer, and therefore all its members,
will be kept alive by its caller so recognize as such.
@rniwa rniwa requested a review from t-rasmud June 2, 2025 20:57
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels Jun 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 2, 2025

@llvm/pr-subscribers-clang-static-analyzer-1

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

Changes

It's safe for a member function of a class or struct to call a function or allocate a local variable with a pointer or a reference to a member variable since "this" pointer, and therefore all its members, will be kept alive by its caller so recognize as such.


Full diff: https://github.com/llvm/llvm-project/pull/142485.diff

6 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp (+15)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h (+4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp (+4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp (+3)
  • (modified) clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp (+16)
  • (modified) clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp (+16)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index f087fc8fa19fd..b6f452e814830 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -231,6 +231,21 @@ bool isConstOwnerPtrMemberExpr(const clang::Expr *E) {
   return isOwnerPtrType(T) && T.isConstQualified();
 }
 
+bool isExprToGetCheckedPtrCapableMember(const clang::Expr *E) {
+  auto *ME = dyn_cast<MemberExpr>(E);
+  if (!ME)
+    return false;
+  auto *D = ME->getMemberDecl();
+  if (!D)
+    return false;
+  auto T = D->getType();
+  auto *CXXRD = T->getAsCXXRecordDecl();
+  if (!CXXRD)
+    return false;
+  auto result = isCheckedPtrCapable(CXXRD);
+  return result && *result;
+}
+
 class EnsureFunctionVisitor
     : public ConstStmtVisitor<EnsureFunctionVisitor, bool> {
 public:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h
index e2cc7b976adfc..8302bbe3084c2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h
@@ -69,6 +69,10 @@ bool isASafeCallArg(const clang::Expr *E);
 /// \returns true if E is a MemberExpr accessing a const smart pointer type.
 bool isConstOwnerPtrMemberExpr(const clang::Expr *E);
 
+/// \returns true if E is a MemberExpr accessing a member variable which
+/// supports CheckedPtr.
+bool isExprToGetCheckedPtrCapableMember(const clang::Expr *E);
+
 /// \returns true if E is a CXXMemberCallExpr which returns a const smart
 /// pointer type.
 class EnsureFunctionAnalysis {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp
index 78675e55cf0ba..6bc39ab565041 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp
@@ -443,6 +443,10 @@ class UncheckedCallArgsChecker final : public RawPtrRefCallArgsChecker {
     return isRefOrCheckedPtrType(type);
   }
 
+  bool isSafeExpr(const Expr *E) const final {
+    return isExprToGetCheckedPtrCapableMember(E);
+  }
+
   const char *ptrKind() const final { return "unchecked"; }
 };
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
index 4fb47703e3984..7cd86a682c0a9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp
@@ -417,6 +417,9 @@ class UncheckedLocalVarsChecker final : public RawPtrRefLocalVarsChecker {
   bool isSafePtrType(const QualType type) const final {
     return isRefOrCheckedPtrType(type);
   }
+  bool isSafeExpr(const Expr *E) const final {
+    return isExprToGetCheckedPtrCapableMember(E);
+  }
   const char *ptrKind() const final { return "unchecked"; }
 };
 
diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp
index e24b04dcd3cf9..4ad365f0f937e 100644
--- a/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp
@@ -32,6 +32,22 @@ static void baz() {
 
 } // namespace call_args_checked
 
+namespace call_args_member {
+
+void consume(CheckedObj&);
+
+struct WrapperObj {
+  CheckedObj checked;
+  CheckedObj& checkedRef;
+  void foo() {
+    consume(checked);
+    consume(checkedRef);
+    // expected-warning@-1{{Call argument is unchecked and unsafe [alpha.webkit.UncheckedCallArgsChecker]}}
+  }
+};
+
+} // namespace call_args_checked
+
 namespace call_args_default {
 
 void someFunction(RefCountableAndCheckable* = makeObj());
diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp
index 3bc75230fcf82..64ab22f74c558 100644
--- a/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp
@@ -290,6 +290,22 @@ void foo() {
 
 } // namespace local_assignment_to_global
 
+namespace member_var {
+
+  struct WrapperObj {
+    CheckedObj checked;
+    CheckedObj& checkedRef;
+    void foo() {
+      auto *a = &checked;
+      a->method();
+      auto *b = &checkedRef;
+      // expected-warning@-1{{Local variable 'b' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}}
+      b->method();
+    }
+  };
+
+}
+
 namespace local_refcountable_checkable_object {
 
 RefCountableAndCheckable* provide_obj();

vitorroriz added a commit to vitorroriz/WebKit that referenced this pull request Jun 4, 2025
https://bugs.webkit.org/show_bug.cgi?id=294050
rdar://problem/152609927

Reviewed by NOBODY (OOPS!).

This should be enough to remove ComplexTextController.cpp
from UncheckedCallArgsCheckerExpectations once [1] on the
static analyzer gets resolved.

We have 2 remaining failures here due to [1] regarding members of TextLayout.

* Source/WebCore/platform/graphics/ComplexTextController.h:

[1] llvm/llvm-project#142485
webkit-commit-queue pushed a commit to vitorroriz/WebKit that referenced this pull request Jun 5, 2025
https://bugs.webkit.org/show_bug.cgi?id=294050
rdar://problem/152609927

Reviewed by Chris Dumez.

This should be enough to remove ComplexTextController.cpp
from UncheckedCallArgsCheckerExpectations once [1] on the
static analyzer gets resolved.

We have 2 remaining failures here due to [1] regarding members of TextLayout.

* Source/WebCore/platform/graphics/ComplexTextController.h:

[1] llvm/llvm-project#142485

Canonical link: https://commits.webkit.org/295845@main
Copy link
Contributor

@ziqingluo-90 ziqingluo-90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rniwa
Copy link
Contributor Author

rniwa commented Jun 9, 2025

Thank you for the review!

@rniwa rniwa merged commit e5fa38b into llvm:main Jun 9, 2025
6 of 7 checks passed
@rniwa rniwa deleted the webkit-treat-checkedptr-capable-member-as-safe branch June 9, 2025 14:32
rniwa added a commit to rniwa/llvm-project that referenced this pull request Jun 9, 2025
… of CheckedPtr as safe. (llvm#142485)

It's safe for a member function of a class or struct to call a function
or allocate a local variable with a pointer or a reference to a member
variable since "this" pointer, and therefore all its members, will be
kept alive by its caller so recognize as such.
rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
… of CheckedPtr as safe. (llvm#142485)

It's safe for a member function of a class or struct to call a function
or allocate a local variable with a pointer or a reference to a member
variable since "this" pointer, and therefore all its members, will be
kept alive by its caller so recognize as such.
DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
… of CheckedPtr as safe. (llvm#142485)

It's safe for a member function of a class or struct to call a function
or allocate a local variable with a pointer or a reference to a member
variable since "this" pointer, and therefore all its members, will be
kept alive by its caller so recognize as such.
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
… of CheckedPtr as safe. (llvm#142485)

It's safe for a member function of a class or struct to call a function
or allocate a local variable with a pointer or a reference to a member
variable since "this" pointer, and therefore all its members, will be
kept alive by its caller so recognize as such.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants