Skip to content

Commit 26f2395

Browse files
committed
[alpha.webkit.UncountedCallArgsChecker] Add the support for calling Ref::ptr accessor.
This accessor returns a pointer from Ref type and is therefore safe.
1 parent a3c6875 commit 26f2395

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ std::optional<bool> isGetterOfRefCounted(const CXXMethodDecl* M)
148148

149149
if (((className == "Ref" || className == "RefPtr") &&
150150
methodName == "get") ||
151+
(className == "Ref" && methodName == "ptr") ||
151152
((className == "String" || className == "AtomString" ||
152153
className == "AtomStringImpl" || className == "UniqueString" ||
153154
className == "UniqueStringImpl" || className == "Identifier") &&
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
2+
// expected-no-diagnostics
3+
4+
#include "ref.h"
5+
6+
class Node {
7+
public:
8+
static Ref<Node> create();
9+
virtual ~Node();
10+
11+
void ref() const;
12+
void deref() const;
13+
14+
protected:
15+
explicit Node();
16+
};
17+
18+
void someFunction(Node*);
19+
20+
void testFunction()
21+
{
22+
Ref node = Node::create();
23+
someFunction(node.ptr());
24+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
template<typename T>
2+
class Ref {
3+
public:
4+
~Ref()
5+
{
6+
if (auto* ptr = m_ptr)
7+
ptr->deref();
8+
m_ptr = nullptr;
9+
}
10+
11+
Ref(T& object)
12+
: m_ptr(&object)
13+
{
14+
object.ref();
15+
}
16+
17+
Ref(const Ref& other)
18+
: m_ptr(other.ptr())
19+
{
20+
m_ptr->ref();
21+
}
22+
23+
template<typename X> Ref(const Ref<X>& other)
24+
: m_ptr(other.ptr())
25+
{
26+
m_ptr->ref();
27+
}
28+
29+
Ref(Ref&& other)
30+
: m_ptr(&other.leakRef())
31+
{
32+
}
33+
34+
template<typename X>
35+
Ref(Ref<X>&& other)
36+
: m_ptr(&other.leakRef())
37+
{
38+
}
39+
40+
T* operator->() const { return m_ptr; }
41+
T* ptr() const { return m_ptr; }
42+
T& get() const { return *m_ptr; }
43+
operator T&() const { return *m_ptr; }
44+
bool operator!() const { return !*m_ptr; }
45+
46+
T& leakRef()
47+
{
48+
T& result = *m_ptr;
49+
m_ptr = nullptr;
50+
return result;
51+
}
52+
53+
private:
54+
template<typename U> friend inline Ref<U> adoptRef(U&);
55+
56+
enum AdoptTag { Adopt };
57+
Ref(T& object, AdoptTag)
58+
: m_ptr(&object)
59+
{
60+
}
61+
62+
T* m_ptr;
63+
};

0 commit comments

Comments
 (0)