Skip to content

Commit

Permalink
[alpha.webkit.UncountedCallArgsChecker] Avoid emitting warnings for R…
Browse files Browse the repository at this point in the history
…ef, RefPtr, and their variants. (llvm#90153)

Skip the analysis of Ref, RefPtr, and their variant classes in
UncountedCallArgsChecker since these classes are "trusted" to not do
anything dangerous.
  • Loading branch information
rniwa authored Apr 26, 2024
1 parent 12d322d commit 3d5e9ab
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 16 deletions.
3 changes: 3 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class);
/// class, false if not, std::nullopt if inconclusive.
std::optional<bool> isUncountedPtr(const clang::Type* T);

/// \returns true if Name is a RefPtr, Ref, or its variant, false if not.
bool isRefType(const std::string &Name);

/// \returns true if \p F creates ref-countable object from uncounted parameter,
/// false if not.
bool isCtorOfRefCounted(const clang::FunctionDecl *F);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class UncountedCallArgsChecker
bool shouldVisitTemplateInstantiations() const { return true; }
bool shouldVisitImplicitCode() const { return false; }

bool TraverseDecl(Decl *D) {
if (isa<ClassTemplateDecl>(D) && isRefType(safeGetName(D)))
return true;
return RecursiveASTVisitor<LocalVisitor>::TraverseDecl(D);
}

bool VisitCallExpr(const CallExpr *CE) {
Checker->visitCallExpr(CE);
return true;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/Checkers/WebKit/call-args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace ref_counted {
void consume_ref_counted(Ref<RefCountable>) {}

void foo() {
consume_refcntbl(provide_ref_counted().get());
consume_refcntbl(provide_ref_counted().ptr());
// no warning
}
}
Expand Down
67 changes: 52 additions & 15 deletions clang/test/Analysis/Checkers/WebKit/mock-types.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,61 @@
#ifndef mock_types_1103988513531
#define mock_types_1103988513531

template <typename T> struct Ref {
T *t;
template<typename T>
struct RawPtrTraits {
using StorageType = T*;

Ref() : t{} {};
Ref(T &t)
: t(t) {
if (t)
t->ref();
template<typename U>
static T* exchange(StorageType& ptr, U&& newValue)
{
StorageType oldValue = static_cast<StorageType&&>(ptr);
ptr = static_cast<U&&>(newValue);
return oldValue;
}
~Ref() {
if (t)
t->deref();

static void swap(StorageType& a, StorageType& b)
{
StorageType temp = static_cast<StorageType&&>(a);
a = static_cast<StorageType&&>(b);
b = static_cast<StorageType&&>(temp);
}
T *get() { return t; }
T *ptr() { return t; }
T *operator->() { return t; }
operator const T &() const { return *t; }
operator T &() { return *t; }
static T* unwrap(const StorageType& ptr) { return ptr; }
};

template<typename T> struct DefaultRefDerefTraits {
static T* refIfNotNull(T* ptr)
{
if (ptr)
ptr->ref();
return ptr;
}

static T& ref(T& ref)
{
ref.ref();
return ref;
}

static void derefIfNotNull(T* ptr)
{
if (ptr)
ptr->deref();
}
};

template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> struct Ref {
typename PtrTraits::StorageType t;

Ref() : t{} {};
Ref(T &t) : t(RefDerefTraits::refIfNotNull(t)) { }
Ref(const Ref& o) : t(RefDerefTraits::refIfNotNull(PtrTraits::unwrap(o.t))) { }
~Ref() { RefDerefTraits::derefIfNotNull(PtrTraits::exchange(t, nullptr)); }
T &get() { return *PtrTraits::unwrap(t); }
T *ptr() { return PtrTraits::unwrap(t); }
T *operator->() { return PtrTraits::unwrap(t); }
operator const T &() const { return *PtrTraits::unwrap(t); }
operator T &() { return *PtrTraits::unwrap(t); }
T* leakRef() { PtrTraits::exchange(t, nullptr); }
};

template <typename T> struct RefPtr {
Expand Down

0 comments on commit 3d5e9ab

Please sign in to comment.