Skip to content

[alpha.webkit.UncheckedCallArgsChecker] Treat copyRef() in a call argument as safe - #220882

Merged
rniwa merged 1 commit into
llvm:mainfrom
rniwa:fix-webkit-call-arg-copy-ref
Sep 3, 2026
Merged

[alpha.webkit.UncheckedCallArgsChecker] Treat copyRef() in a call argument as safe#220882
rniwa merged 1 commit into
llvm:mainfrom
rniwa:fix-webkit-call-arg-copy-ref

Conversation

@rniwa

@rniwa rniwa commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Treat calling a non-trivial function with the result of copyRef() or any other function which returns a safe pointer type as an argument as safe.

…ument as safe

Treat calling a non-trivial function with the result of copyRef() or any other function
which returns a safe pointer type as an argument as safe.
@rniwa
rniwa requested a review from steakhal September 3, 2026 11:31
@llvmorg-github-actions llvmorg-github-actions Bot added clang Clang issues not falling into any other category clang:static analyzer labels Sep 3, 2026
@rniwa
rniwa requested a review from t-rasmud September 3, 2026 11:31
@llvmorg-github-actions

llvmorg-github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

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

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

Changes

Treat calling a non-trivial function with the result of copyRef() or any other function which returns a safe pointer type as an argument as safe.


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

4 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp (+3)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+3)
  • (modified) clang/test/Analysis/Checkers/WebKit/mock-types.h (+1)
  • (modified) clang/test/Analysis/Checkers/WebKit/unchecked-call-arg.cpp (+23)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index 5fd2ff87bce8d..e8f69f1aac757 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -104,6 +104,9 @@ bool tryToFindPtrOrigin(
         }
       }
 
+      if (isSafePtrType(call->getType()))
+        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/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index d5fb88a15b6de..37347c51d4ca2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -219,6 +219,9 @@ static bool isPtrOfType(const clang::QualType T, Predicate Pred) {
     } else if (auto *DTS = type->getAs<DeducedTemplateSpecializationType>()) {
       auto *Decl = DTS->getTemplateName().getAsTemplateDecl();
       return Decl && Pred(Decl->getNameAsString());
+    } else if (auto *RD = type->getAs<RecordType>()) {
+      auto *Decl = RD->getDecl();
+      return Decl && Pred(Decl->getNameAsString());
     } else
       break;
   }
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h
index dea16f534ba2b..9ed5ecab88c6e 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h
@@ -318,6 +318,7 @@ template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTra
   T *operator->() const { return PtrTraits::unwrap(t); }
   operator T &() const { return *PtrTraits::unwrap(t); }
   T* leakRef() { return PtrTraits::exchange(t, nullptr); }
+  [[nodiscard]] Ref copyRef() const { return Ref(*t); }
 };
 
 template <typename T> Ref<T> adoptRef(T& t) {
diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-call-arg.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-call-arg.cpp
index b3a338f767afd..c919888d22491 100644
--- a/clang/test/Analysis/Checkers/WebKit/unchecked-call-arg.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/unchecked-call-arg.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedCallArgsChecker -verify %s
 
+#include "mock-types.h"
+
 void WTFCrash(void);
 
 enum class Tag : bool { Value };
@@ -37,3 +39,24 @@ void doWorkWithObject(const CheckedObject&);
 void bar() {
   doWorkWithObject(CheckedObject());
 }
+
+namespace refptr_checked_ptr_capable {
+
+class CheckedRefCounted {
+public:
+  void ref() const;
+  void deref() const;
+  void incrementCheckedPtrCount() const;
+  void decrementCheckedPtrCount() const;
+};
+
+void receive(CheckedRefCounted&);
+struct Foo {
+  Ref<CheckedRefCounted> m_obj;
+
+  void foo() {
+    receive(m_obj.copyRef());
+  }
+};
+
+} // namespace refptr_checked_ptr_capable

@rniwa
rniwa merged commit 1831383 into llvm:main Sep 3, 2026
15 checks passed
@rniwa
rniwa deleted the fix-webkit-call-arg-copy-ref branch September 3, 2026 13:32
Iasonaskrpr pushed a commit to Iasonaskrpr/llvm-project that referenced this pull request Sep 4, 2026
…ument as safe (llvm#220882)

Treat calling a non-trivial function with the result of copyRef() or any
other function which returns a safe pointer type as an argument as safe.
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.

2 participants