Skip to content

Commit 6b4a6b8

Browse files
committed
[WebKit checkers] Recognize adoptRef as a safe function
adoptRef in WebKit constructs Ref/RefPtr so treat it as such in isCtorOfRefCounted. Also removed the support for makeRef and makeRefPtr as they don't exist any more.
1 parent dd8d85d commit 6b4a6b8

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,8 @@ bool isCtorOfRefCounted(const clang::FunctionDecl *F) {
125125
assert(F);
126126
const std::string &FunctionName = safeGetName(F);
127127

128-
return isRefType(FunctionName) || FunctionName == "makeRef" ||
129-
FunctionName == "makeRefPtr" || FunctionName == "UniqueRef" ||
130-
FunctionName == "makeUniqueRef" ||
128+
return isRefType(FunctionName) || FunctionName == "adoptRef" ||
129+
FunctionName == "UniqueRef" || FunctionName == "makeUniqueRef" ||
131130
FunctionName == "makeUniqueRefWithoutFastMallocCheck"
132131

133132
|| FunctionName == "String" || FunctionName == "AtomString" ||

clang/test/Analysis/Checkers/WebKit/call-args.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,20 @@ namespace call_with_explicit_temporary_obj {
365365
RefPtr { provide() }->method();
366366
}
367367
}
368+
369+
namespace call_with_adopt_ref {
370+
class Obj {
371+
public:
372+
void ref() const;
373+
void deref() const;
374+
void method();
375+
};
376+
377+
struct dummy {
378+
RefPtr<Obj> any;
379+
};
380+
381+
void foo() {
382+
adoptRef(new Obj)->method();
383+
}
384+
}

clang/test/Analysis/Checkers/WebKit/mock-types.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ template<typename T> struct DefaultRefDerefTraits {
4646
template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> struct Ref {
4747
typename PtrTraits::StorageType t;
4848

49+
enum AdoptTag { Adopt };
50+
4951
Ref() : t{} {};
52+
Ref(T &t, AdoptTag) : t(&t) { }
5053
Ref(T &t) : t(&RefDerefTraits::ref(t)) { }
5154
Ref(const Ref& o) : t(RefDerefTraits::refIfNotNull(PtrTraits::unwrap(o.t))) { }
5255
Ref(Ref&& o) : t(o.leakRef()) { }
@@ -73,10 +76,19 @@ template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTra
7376
T* leakRef() { return PtrTraits::exchange(t, nullptr); }
7477
};
7578

79+
template <typename T> Ref<T> adoptRef(T& t) {
80+
using Ref = Ref<T>;
81+
return Ref(t, Ref::Adopt);
82+
}
83+
84+
template<typename T> class RefPtr;
85+
template<typename T> RefPtr<T> adoptRef(T*);
86+
7687
template <typename T> struct RefPtr {
7788
T *t;
7889

79-
RefPtr() : t(new T) {}
90+
RefPtr() : t(nullptr) { }
91+
8092
RefPtr(T *t)
8193
: t(t) {
8294
if (t)
@@ -85,6 +97,9 @@ template <typename T> struct RefPtr {
8597
RefPtr(Ref<T>&& o)
8698
: t(o.leakRef())
8799
{ }
100+
RefPtr(RefPtr&& o)
101+
: t(o.leakRef())
102+
{ }
88103
~RefPtr() {
89104
if (t)
90105
t->deref();
@@ -110,8 +125,19 @@ template <typename T> struct RefPtr {
110125
return *this;
111126
}
112127
operator bool() const { return t; }
128+
129+
private:
130+
friend RefPtr adoptRef<T>(T*);
131+
132+
// call_with_adopt_ref in call-args.cpp requires this method to be private.
133+
enum AdoptTag { Adopt };
134+
RefPtr(T *t, AdoptTag) : t(t) { }
113135
};
114136

137+
template <typename T> RefPtr<T> adoptRef(T* t) {
138+
return RefPtr<T>(t, RefPtr<T>::Adopt);
139+
}
140+
115141
template <typename T> bool operator==(const RefPtr<T> &, const RefPtr<T> &) {
116142
return false;
117143
}

0 commit comments

Comments
 (0)