-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the support for calling Ref::ptr accessor. #80919
Conversation
@llvm/pr-subscribers-clang Author: Ryosuke Niwa (rniwa) ChangesThis accessor returns a pointer from Ref type and is therefore safe. Full diff: https://github.com/llvm/llvm-project/pull/80919.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index c1f180f31338cb..4bc3f7a8c9c3ce 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -148,6 +148,7 @@ std::optional<bool> isGetterOfRefCounted(const CXXMethodDecl* M)
if (((className == "Ref" || className == "RefPtr") &&
methodName == "get") ||
+ (className == "Ref" && methodName == "ptr") ||
((className == "String" || className == "AtomString" ||
className == "AtomStringImpl" || className == "UniqueString" ||
className == "UniqueStringImpl" || className == "Identifier") &&
diff --git a/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp b/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp
new file mode 100644
index 00000000000000..d3185a9f2d58a4
--- /dev/null
+++ b/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
+// expected-no-diagnostics
+
+template<typename T>
+class Ref {
+public:
+ ~Ref()
+ {
+ if (auto* ptr = m_ptr)
+ ptr->deref();
+ m_ptr = nullptr;
+ }
+
+ Ref(T& object)
+ : m_ptr(&object)
+ {
+ object.ref();
+ }
+
+ Ref(const Ref& other)
+ : m_ptr(other.ptr())
+ {
+ m_ptr->ref();
+ }
+
+ template<typename X> Ref(const Ref<X>& other)
+ : m_ptr(other.ptr())
+ {
+ m_ptr->ref();
+ }
+
+ Ref(Ref&& other)
+ : m_ptr(&other.leakRef())
+ {
+ }
+
+ template<typename X>
+ Ref(Ref<X>&& other)
+ : m_ptr(&other.leakRef())
+ {
+ }
+
+ T* operator->() const { return m_ptr; }
+ T* ptr() const { return m_ptr; }
+ T& get() const { return *m_ptr; }
+ operator T&() const { return *m_ptr; }
+ bool operator!() const { return !*m_ptr; }
+
+ T& leakRef()
+ {
+ T& result = *m_ptr;
+ m_ptr = nullptr;
+ return result;
+ }
+
+private:
+ template<typename U> friend inline Ref<U> adoptRef(U&);
+
+ enum AdoptTag { Adopt };
+ Ref(T& object, AdoptTag)
+ : m_ptr(&object)
+ {
+ }
+
+ T* m_ptr;
+};
+
+class Node {
+public:
+ static Ref<Node> create();
+ virtual ~Node();
+
+ void ref() const;
+ void deref() const;
+
+protected:
+ explicit Node();
+};
+
+void someFunction(Node*);
+
+void testFunction()
+{
+ Ref node = Node::create();
+ someFunction(node.ptr());
+}
|
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Ryosuke Niwa (rniwa) ChangesThis accessor returns a pointer from Ref type and is therefore safe. Full diff: https://github.com/llvm/llvm-project/pull/80919.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index c1f180f31338c..4bc3f7a8c9c3c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -148,6 +148,7 @@ std::optional<bool> isGetterOfRefCounted(const CXXMethodDecl* M)
if (((className == "Ref" || className == "RefPtr") &&
methodName == "get") ||
+ (className == "Ref" && methodName == "ptr") ||
((className == "String" || className == "AtomString" ||
className == "AtomStringImpl" || className == "UniqueString" ||
className == "UniqueStringImpl" || className == "Identifier") &&
diff --git a/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp b/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp
new file mode 100644
index 0000000000000..d3185a9f2d58a
--- /dev/null
+++ b/clang/test/Analysis/Checkers/WebKit/ref-ptr-accessor.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s
+// expected-no-diagnostics
+
+template<typename T>
+class Ref {
+public:
+ ~Ref()
+ {
+ if (auto* ptr = m_ptr)
+ ptr->deref();
+ m_ptr = nullptr;
+ }
+
+ Ref(T& object)
+ : m_ptr(&object)
+ {
+ object.ref();
+ }
+
+ Ref(const Ref& other)
+ : m_ptr(other.ptr())
+ {
+ m_ptr->ref();
+ }
+
+ template<typename X> Ref(const Ref<X>& other)
+ : m_ptr(other.ptr())
+ {
+ m_ptr->ref();
+ }
+
+ Ref(Ref&& other)
+ : m_ptr(&other.leakRef())
+ {
+ }
+
+ template<typename X>
+ Ref(Ref<X>&& other)
+ : m_ptr(&other.leakRef())
+ {
+ }
+
+ T* operator->() const { return m_ptr; }
+ T* ptr() const { return m_ptr; }
+ T& get() const { return *m_ptr; }
+ operator T&() const { return *m_ptr; }
+ bool operator!() const { return !*m_ptr; }
+
+ T& leakRef()
+ {
+ T& result = *m_ptr;
+ m_ptr = nullptr;
+ return result;
+ }
+
+private:
+ template<typename U> friend inline Ref<U> adoptRef(U&);
+
+ enum AdoptTag { Adopt };
+ Ref(T& object, AdoptTag)
+ : m_ptr(&object)
+ {
+ }
+
+ T* m_ptr;
+};
+
+class Node {
+public:
+ static Ref<Node> create();
+ virtual ~Node();
+
+ void ref() const;
+ void deref() const;
+
+protected:
+ explicit Node();
+};
+
+void someFunction(Node*);
+
+void testFunction()
+{
+ Ref node = Node::create();
+ someFunction(node.ptr());
+}
|
63a64cf
to
b117f4c
Compare
b117f4c
to
26f2395
Compare
…ef::ptr accessor. This accessor returns a pointer from Ref type and is therefore safe.
26f2395
to
6476d4c
Compare
This accessor returns a pointer from Ref type and is therefore safe. (cherry picked from commit 8256804)
This accessor returns a pointer from Ref type and is therefore safe.