https://github.com/rniwa created https://github.com/llvm/llvm-project/pull/80810
None >From 81057ef7e57f0e61d4b3edb19a7e6dc2b196b824 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <rn...@webkit.org> Date: Tue, 6 Feb 2024 01:13:34 -0800 Subject: [PATCH] Ignore assignment to Ref / RefPtr in alpha.webkit.UncountedCallArgsChecker. --- .../WebKit/UncountedCallArgsChecker.cpp | 9 +++ .../Checkers/WebKit/assignment-to-refptr.cpp | 71 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 clang/test/Analysis/Checkers/WebKit/assignment-to-refptr.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp index 407b6ba7a76428..b9ccf46f52649f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp @@ -126,6 +126,15 @@ class UncountedCallArgsChecker // of object on LHS. if (auto *MemberOp = dyn_cast<CXXOperatorCallExpr>(CE)) { // Note: assignemnt to built-in type isn't derived from CallExpr. + if (MemberOp->getOperator() == OO_Equal) { // Ignore assignment to Ref/RefPtr. + auto *callee = MemberOp->getDirectCallee(); + if (auto *calleeDecl = dyn_cast<CXXMethodDecl>(callee)) { + if (const CXXRecordDecl *classDecl = calleeDecl->getParent()) { + if (isRefCounted(classDecl)) + return true; + } + } + } if (MemberOp->isAssignmentOp()) return false; } diff --git a/clang/test/Analysis/Checkers/WebKit/assignment-to-refptr.cpp b/clang/test/Analysis/Checkers/WebKit/assignment-to-refptr.cpp new file mode 100644 index 00000000000000..c8ad634a5493f5 --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/assignment-to-refptr.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s +// expected-no-diagnostics + +template<typename T> +class RefPtr { +public: + inline constexpr RefPtr() : m_ptr(nullptr) { } + inline RefPtr(T* ptr) + : m_ptr(ptr) + { + if (m_ptr) + m_ptr->ref(); + } + + inline RefPtr(const RefPtr& o) + : m_ptr(o.m_ptr) + { + if (m_ptr) + m_ptr->ref(); + } + + inline ~RefPtr() + { + if (m_ptr) + m_ptr->deref(); + } + + inline T* operator->() const { return m_ptr; } + explicit operator bool() const { return m_ptr; } + + RefPtr& operator=(const RefPtr&); + RefPtr& operator=(T*); + +private: + T* m_ptr; +}; + +template<typename T> +inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr& o) +{ + if (m_ptr) + m_ptr->deref(); + m_ptr = o.m_ptr; + if (m_ptr) + m_ptr->ref(); + return *this; +} + +template<typename T> +inline RefPtr<T>& RefPtr<T>::operator=(T* optr) +{ + if (m_ptr) + m_ptr->deref(); + m_ptr = optr; + if (m_ptr) + m_ptr->ref(); + return *this; +} + +class Node { +public: + Node* nextSibling() const; + + void ref() const; + void deref() const; +}; + +static void removeDetachedChildren(Node* firstChild) +{ + for (RefPtr child = firstChild; child; child = child->nextSibling()); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits