Skip to content

Commit b117f4c

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 b117f4c

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-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: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
2+
// expected-no-diagnostics
3+
4+
template<typename T>
5+
class Ref {
6+
public:
7+
~Ref()
8+
{
9+
if (auto* ptr = m_ptr)
10+
ptr->deref();
11+
m_ptr = nullptr;
12+
}
13+
14+
Ref(T& object)
15+
: m_ptr(&object)
16+
{
17+
object.ref();
18+
}
19+
20+
Ref(const Ref& other)
21+
: m_ptr(other.ptr())
22+
{
23+
m_ptr->ref();
24+
}
25+
26+
template<typename X> Ref(const Ref<X>& other)
27+
: m_ptr(other.ptr())
28+
{
29+
m_ptr->ref();
30+
}
31+
32+
Ref(Ref&& other)
33+
: m_ptr(&other.leakRef())
34+
{
35+
}
36+
37+
template<typename X>
38+
Ref(Ref<X>&& other)
39+
: m_ptr(&other.leakRef())
40+
{
41+
}
42+
43+
T* operator->() const { return m_ptr; }
44+
T* ptr() const { return m_ptr; }
45+
T& get() const { return *m_ptr; }
46+
operator T&() const { return *m_ptr; }
47+
bool operator!() const { return !*m_ptr; }
48+
49+
T& leakRef()
50+
{
51+
T& result = *m_ptr;
52+
m_ptr = nullptr;
53+
return result;
54+
}
55+
56+
private:
57+
template<typename U> friend inline Ref<U> adoptRef(U&);
58+
59+
enum AdoptTag { Adopt };
60+
Ref(T& object, AdoptTag)
61+
: m_ptr(&object)
62+
{
63+
}
64+
65+
T* m_ptr;
66+
};
67+
68+
class Node {
69+
public:
70+
static Ref<Node> create();
71+
virtual ~Node();
72+
73+
void ref() const;
74+
void deref() const;
75+
76+
protected:
77+
explicit Node();
78+
};
79+
80+
void someFunction(Node*);
81+
82+
void testFunction()
83+
{
84+
Ref node = Node::create();
85+
someFunction(node.ptr());
86+
}

0 commit comments

Comments
 (0)