https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/219647
>From 6f93383031ab95de11485345e20ee4914cee6498 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Fri, 28 Aug 2026 17:01:32 -0700 Subject: [PATCH 1/3] [alpha.webkit.UncountedLocalVarsChecker] Support obtaining guardian's value via operator* This PR fixes a bug in alpha.webkit.UncountedLocalVarsChecker that it wasn't allowing a guardian variable's getter to be called when initializing a raw pointer/reference. Also fix a bug that operator* wasn't recognized as a valid getter on a smart pointer. --- .../Checkers/WebKit/PtrTypesSemantics.cpp | 7 +++++-- .../WebKit/RawPtrRefLocalVarsChecker.cpp | 5 +++++ .../Analysis/Checkers/WebKit/mock-types.h | 3 ++- .../Checkers/WebKit/uncounted-local-vars.cpp | 19 ++++++++++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index e8e404c753dcb..eb5960c262c95 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -357,10 +357,13 @@ std::optional<bool> isGetterOfSafePtr(const CXXMethodDecl *M) { std::string className = safeGetName(calleeMethodsClass); std::string method = safeGetName(M); - if (isCheckedPtr(className) && (method == "get" || method == "ptr")) + auto OpType = M->getOverloadedOperator(); + if (isCheckedPtr(className) && + (method == "get" || method == "ptr" || OpType == OO_Star)) return true; - if ((isRefType(className) && (method == "get" || method == "ptr")) || + if ((isRefType(className) && + (method == "get" || method == "ptr" || OpType == OO_Star)) || ((className == "String" || className == "AtomString" || className == "AtomStringImpl" || className == "UniqueString" || className == "UniqueStringImpl" || className == "Identifier") && diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index b420ce73ae82e..f3c620436f7a4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -89,6 +89,11 @@ struct GuardianVisitor : DynamicRecursiveASTVisitor { return false; if (isPtrConversion(Callee)) return true; + if (auto *Method = dyn_cast<CXXMethodDecl>(Callee)) { + auto IsGetter = isGetterOfSafePtr(Method); + if (IsGetter && *IsGetter) + return true; + } unsigned ArgIndex = 0; unsigned ArgOffset = isa<CXXOperatorCallExpr>(CE); for (auto *Arg : CE->arguments()) { diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index 87b495f526f27..dea16f534ba2b 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -435,7 +435,8 @@ struct RefCountable { unsigned m_refCount { 0 }; }; -template <typename T> T *downcast(T *t) { return t; } +template <typename U, typename T> U [[clang::annotate_type("webkit.pointerconversion")]] *downcast(T *t) { return static_cast<U*>(t); } +template <typename U, typename T> U [[clang::annotate_type("webkit.pointerconversion")]] &downcast(T &t) { return static_cast<U&>(t); } template <typename T> struct CheckedRef { private: diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp index d36e78f12453f..31990217525c1 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp @@ -214,6 +214,23 @@ void foo9(RefCountable& o) { } } +RefCountable* provide(); + +struct Derived : public RefCountable { +}; + +void foo10() { + RefPtr<RefCountable> obj = provide(); + if (obj) { + auto* ptr = downcast<Derived>(obj.get()); + ptr->method(); + } + if (obj) { + auto& ref = downcast<Derived>(*obj); + ref.method(); + } +} + } // namespace guardian_scopes namespace auto_keyword { @@ -705,4 +722,4 @@ namespace binding_raw_ptr { a->method(); } -} \ No newline at end of file +} >From f7880a565329860c27102a9ceedb180566f5600a Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Mon, 31 Aug 2026 09:09:34 +0900 Subject: [PATCH 2/3] Address the review comment. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- .../Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index f3c620436f7a4..7f5c82a3437bd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -90,8 +90,7 @@ struct GuardianVisitor : DynamicRecursiveASTVisitor { if (isPtrConversion(Callee)) return true; if (auto *Method = dyn_cast<CXXMethodDecl>(Callee)) { - auto IsGetter = isGetterOfSafePtr(Method); - if (IsGetter && *IsGetter) + if (isGetterOfSafePtr(Method).value_or(false)) return true; } unsigned ArgIndex = 0; >From af008a89ed4f1cdd47cc6af7ce340e23d063194a Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Mon, 31 Aug 2026 11:21:12 +0900 Subject: [PATCH 3/3] Fix tests --- clang/test/Analysis/Checkers/WebKit/objc-mock-types.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h index ee9ac937eb0bf..aad2a6185d0b0 100644 --- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h @@ -273,8 +273,6 @@ template<typename T> RetainPtr<T> adoptNSNullable(T*); template<typename T> RetainPtr<T> adoptCF(T); template<typename T> RetainPtr<T> adoptCFNullable(T); -template <typename T, typename S> T *downcast(S *t) { return static_cast<T*>(t); } - template <typename T> struct RemovePointer { typedef T Type; }; @@ -713,7 +711,6 @@ using WTF::adoptCFNullable; using WTF::retainPtr; using WTF::OSObjectPtr; using WTF::adoptOSObject; -using WTF::downcast; using WTF::bridge_cast; using WTF::bridge_id_cast; using WTF::is_objc; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
