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(call)) { if (auto *decl = memberCall->getMethodDecl()) { std::optional 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()) { auto *Decl = DTS->getTemplateName().getAsTemplateDecl(); return Decl && Pred(Decl->getNameAsString()); + } else if (auto *RD = type->getAs()) { + 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 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 Ref 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 m_obj; + + void foo() { + receive(m_obj.copyRef()); + } +}; + +} // namespace refptr_checked_ptr_capable