From 9cda4ca6bff42b4afb6a63ce5f81793fcc9a04f3 Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Mon, 11 Jul 2016 02:23:59 -0700 Subject: [PATCH] Add models of shared_ptr comparison operators Reviewed By: jvillard Differential Revision: D3534300 fbshipit-source-id: a95ecf4 --- .../cpp/include/infer_model/shared_ptr.h | 96 +++++++++++++++++++ .../cpp/errors/smart_ptr/shared_ptr_deref.cpp | 20 ++++ 2 files changed, 116 insertions(+) diff --git a/infer/models/cpp/include/infer_model/shared_ptr.h b/infer/models/cpp/include/infer_model/shared_ptr.h index ceb7d4c9d..b26f0bbe2 100644 --- a/infer/models/cpp/include/infer_model/shared_ptr.h +++ b/infer/models/cpp/include/infer_model/shared_ptr.h @@ -214,6 +214,102 @@ class shared_ptr : public std__shared_ptr { return true; /* FIXME - use non-det */ } }; +template +inline bool operator==(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + return __x.get() == __y.get(); +} + +template +inline bool operator!=(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + return !(__x == __y); +} + +template +inline bool operator<(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + typedef typename common_type<_Tp*, _Up*>::type _Vp; + return less<_Vp>()(__x.get(), __y.get()); +} + +template +inline bool operator>(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + return __y < __x; +} + +template +inline bool operator<=(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + return !(__y < __x); +} + +template +inline bool operator>=(const shared_ptr<_Tp>& __x, + const shared_ptr<_Up>& __y) noexcept { + return !(__x < __y); +} + +template +inline bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return !__x; +} + +template +inline bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return !__x; +} + +template +inline bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return static_cast(__x); +} + +template +inline bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return static_cast(__x); +} + +template +inline bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return less<_Tp*>()(__x.get(), nullptr); +} + +template +inline bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return less<_Tp*>()(nullptr, __x.get()); +} + +template +inline bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return nullptr < __x; +} + +template +inline bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return __x < nullptr; +} + +template +inline bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return !(nullptr < __x); +} + +template +inline bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return !(__x < nullptr); +} + +template +inline bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { + return !(__x < nullptr); +} + +template +inline bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return !(nullptr < __x); +} template struct hash> : public hash> {}; diff --git a/infer/tests/codetoanalyze/cpp/errors/smart_ptr/shared_ptr_deref.cpp b/infer/tests/codetoanalyze/cpp/errors/smart_ptr/shared_ptr_deref.cpp index d90122b7f..228c8a2ad 100644 --- a/infer/tests/codetoanalyze/cpp/errors/smart_ptr/shared_ptr_deref.cpp +++ b/infer/tests/codetoanalyze/cpp/errors/smart_ptr/shared_ptr_deref.cpp @@ -107,3 +107,23 @@ int shared_ptr_move_null_deref() { std::shared_ptr p2 = std::move(p1); return *p1; } + +int shared_ptr_check_null() { + std::shared_ptr p; + if (p == nullptr) + return 1; + return *p; +} + +int shared_ptr_check_notnull() { + std::shared_ptr p; + if (p != nullptr) + return *p; + return 1; +} + +int shared_ptr_check_null2(std::shared_ptr p) { + if (p == nullptr) + return 1; + return *p; +}