Skip to content

Commit 98c97d4

Browse files
authored
[WebKit checkers] Recognize adoptRef as a safe function (#119846)
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 395a369 commit 98c97d4

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,21 @@ namespace call_with_explicit_temporary_obj {
376376

377377
namespace call_with_explicit_construct {
378378
}
379+
380+
namespace call_with_adopt_ref {
381+
class Obj {
382+
public:
383+
void ref() const;
384+
void deref() const;
385+
void method();
386+
};
387+
388+
// This is needed due to rdar://141692212.
389+
struct dummy {
390+
RefPtr<Obj> any;
391+
};
392+
393+
void foo() {
394+
adoptRef(new Obj)->method();
395+
}
396+
}

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ template<typename T> struct DefaultRefDerefTraits {
7474
template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> struct Ref {
7575
typename PtrTraits::StorageType t;
7676

77+
enum AdoptTag { Adopt };
78+
7779
Ref() : t{} {};
80+
Ref(T &t, AdoptTag) : t(&t) { }
7881
Ref(T &t) : t(&RefDerefTraits::ref(t)) { }
7982
Ref(const Ref& o) : t(RefDerefTraits::refIfNotNull(PtrTraits::unwrap(o.t))) { }
8083
Ref(Ref&& o) : t(o.leakRef()) { }
@@ -101,10 +104,19 @@ template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTra
101104
T* leakRef() { return PtrTraits::exchange(t, nullptr); }
102105
};
103106

107+
template <typename T> Ref<T> adoptRef(T& t) {
108+
using Ref = Ref<T>;
109+
return Ref(t, Ref::Adopt);
110+
}
111+
112+
template<typename T> class RefPtr;
113+
template<typename T> RefPtr<T> adoptRef(T*);
114+
104115
template <typename T> struct RefPtr {
105116
T *t;
106117

107-
RefPtr() : t(new T) {}
118+
RefPtr() : t(nullptr) { }
119+
108120
RefPtr(T *t)
109121
: t(t) {
110122
if (t)
@@ -113,6 +125,17 @@ template <typename T> struct RefPtr {
113125
RefPtr(Ref<T>&& o)
114126
: t(o.leakRef())
115127
{ }
128+
RefPtr(RefPtr&& o)
129+
: t(o.t)
130+
{
131+
o.t = nullptr;
132+
}
133+
RefPtr(const RefPtr& o)
134+
: t(o.t)
135+
{
136+
if (t)
137+
t->ref();
138+
}
116139
~RefPtr() {
117140
if (t)
118141
t->deref();
@@ -138,8 +161,19 @@ template <typename T> struct RefPtr {
138161
return *this;
139162
}
140163
operator bool() const { return t; }
164+
165+
private:
166+
friend RefPtr adoptRef<T>(T*);
167+
168+
// call_with_adopt_ref in call-args.cpp requires this method to be private.
169+
enum AdoptTag { Adopt };
170+
RefPtr(T *t, AdoptTag) : t(t) { }
141171
};
142172

173+
template <typename T> RefPtr<T> adoptRef(T* t) {
174+
return RefPtr<T>(t, RefPtr<T>::Adopt);
175+
}
176+
143177
template <typename T> bool operator==(const RefPtr<T> &, const RefPtr<T> &) {
144178
return false;
145179
}

clang/test/Analysis/Checkers/WebKit/ref-cntbl-crtp-base-no-virtual-dtor.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,6 @@ template<typename Out, typename... In> Function<Out(In...)> adopt(Detail::Callab
6161
return Function<Out(In...)>(impl, Function<Out(In...)>::Adopt);
6262
}
6363

64-
template<typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> Ref<T, PtrTraits, RefDerefTraits> adoptRef(T&);
65-
66-
template<typename T, typename _PtrTraits, typename RefDerefTraits>
67-
inline Ref<T, _PtrTraits, RefDerefTraits> adoptRef(T& reference)
68-
{
69-
return Ref<T, _PtrTraits, RefDerefTraits>(reference);
70-
}
71-
7264
enum class DestructionThread : unsigned char { Any, Main, MainRunLoop };
7365
void ensureOnMainThread(Function<void()>&&); // Sync if called on main thread, async otherwise.
7466
void ensureOnMainRunLoop(Function<void()>&&); // Sync if called on main run loop, async otherwise.

0 commit comments

Comments
 (0)