diff --git a/infer/models/cpp/include/infer_model/shared_ptr.h b/infer/models/cpp/include/infer_model/shared_ptr.h index b26f0bbe2..d9b6fdb51 100644 --- a/infer/models/cpp/include/infer_model/shared_ptr.h +++ b/infer/models/cpp/include/infer_model/shared_ptr.h @@ -12,65 +12,72 @@ #include -INFER_NAMESPACE_STD_BEGIN +// define shared_ptr outside of std namespace. It will be aliased as +// std::shared_ptr via 'using' clause later +namespace infer_std_model { // use inheritance to avoid compilation errors when using // methods / non-member functions that are not modeled // WARNING: sizeof(shared_ptr) = 24, not 16 - this may // lead to compilation errors template -class shared_ptr : public std__shared_ptr { +class shared_ptr : public std::std__shared_ptr { public: #if INFER_USE_LIBCPP - using std__shared_ptr::__ptr_; + using std::std__shared_ptr::__ptr_; #define __data __ptr_ #else - using __shared_ptr::_M_ptr; + using std::__shared_ptr::_M_ptr; #define __data _M_ptr #endif // Conversion constructors to allow implicit conversions. // it's here purely to avoid compilation errors template ::value>::type> - shared_ptr(const std__shared_ptr& r) {} + typename = typename std::enable_if< + std::is_convertible::value>::type> + shared_ptr(const std::std__shared_ptr& r) {} template - shared_ptr(const std__shared_ptr& r, T* p) noexcept {} + shared_ptr(const std::std__shared_ptr& r, T* p) noexcept {} // constructors: constexpr shared_ptr() noexcept { __data = nullptr; } - shared_ptr(nullptr_t) : shared_ptr() {} + shared_ptr(std::nullptr_t) : shared_ptr() {} // Extra template argument is used to create constructors/assignment overloads // for Y types where it's possible to convert Y* to T*. - // typename = typename enable_if::value>::type + // typename = typename std::enable_if::value>::type // thanks to that, clang will not create some functions that would cause // compilation errors. More info: // http://en.cppreference.com/w/cpp/language/sfinae template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> explicit shared_ptr(Y* p) { __data = p; } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr(Y* p, D d) : shared_ptr(p) {} template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr(Y* p, D d, A a) : shared_ptr(p) {} template - shared_ptr(nullptr_t p, D d) : shared_ptr(p) {} + shared_ptr(std::nullptr_t p, D d) : shared_ptr(p) {} template - shared_ptr(nullptr_t p, D d, A a) : shared_ptr(p) {} + shared_ptr(std::nullptr_t p, D d, A a) : shared_ptr(p) {} template shared_ptr(const shared_ptr& r, T* p) noexcept { @@ -82,7 +89,8 @@ class shared_ptr : public std__shared_ptr { } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr(const shared_ptr& r) noexcept : shared_ptr(r.__data) { /* TODO - increase refcount*/ } @@ -92,14 +100,16 @@ class shared_ptr : public std__shared_ptr { } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr(shared_ptr&& r) noexcept : shared_ptr(r.__data) { r.__data = nullptr; } template ::value>::type> - explicit shared_ptr(const weak_ptr& r) {} + typename = typename std::enable_if< + std::is_convertible::value>::type> + explicit shared_ptr(const std::weak_ptr& r) {} /* Because of implementation differences between libc++ and stdlibc++, don't * define this constructor (it will be defined elsewhere in case of @@ -107,14 +117,15 @@ class shared_ptr : public std__shared_ptr { * converts to T* - otherwise there might be compilation error (out-of-line * definition). * No definition here might cause compilation problems if project is - * using auto_ptrs with libc++ */ + * using std::auto_ptrs with libc++ */ template - shared_ptr(auto_ptr&& r); // {} + shared_ptr(std::auto_ptr&& r); // {} template ::value>::type> - shared_ptr(unique_ptr&& r) : shared_ptr(r.release()) {} + typename = typename std::enable_if< + std::is_convertible::value>::type> + shared_ptr(std::unique_ptr&& r) : shared_ptr(r.release()) {} // destructor: ~shared_ptr() { reset((T*)nullptr); } @@ -127,7 +138,8 @@ class shared_ptr : public std__shared_ptr { } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr& operator=(const shared_ptr& r) noexcept { // shared_ptr(r).swap(*this); __data = r.__data; @@ -141,7 +153,8 @@ class shared_ptr : public std__shared_ptr { } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> shared_ptr& operator=(shared_ptr&& r) { // shared_ptr(std::move(r)).swap(*this); __data = r.__data; @@ -149,13 +162,15 @@ class shared_ptr : public std__shared_ptr { } template ::value>::type> - shared_ptr& operator=(auto_ptr&& r) { /* ?? */ + typename = typename std::enable_if< + std::is_convertible::value>::type> + shared_ptr& operator=(std::auto_ptr&& r) { /* ?? */ } template ::value>::type> - shared_ptr& operator=(unique_ptr&& r) { + typename = typename std::enable_if< + std::is_convertible::value>::type> + shared_ptr& operator=(std::unique_ptr&& r) { // shared_ptr(std::move(r)).swap(*this); return *this; } @@ -170,7 +185,8 @@ class shared_ptr : public std__shared_ptr { void reset() noexcept { reset((T*)nullptr); } template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> void reset(Y* p) { /* if (unique()) { @@ -183,7 +199,8 @@ class shared_ptr : public std__shared_ptr { template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> void reset(Y* p, D d) { reset(p); } @@ -191,14 +208,15 @@ class shared_ptr : public std__shared_ptr { template ::value>::type> + typename = typename std::enable_if< + std::is_convertible::value>::type> void reset(Y* p, D d, A a) { reset(p); } // observers: T* get() const noexcept { return __data; } - typename add_lvalue_reference::type operator*() const noexcept { + typename std::add_lvalue_reference::type operator*() const noexcept { return *__data; } T* operator->() const noexcept { return __data; } @@ -210,10 +228,11 @@ class shared_ptr : public std__shared_ptr { return true; /* FIXME - use non-det*/ } template - bool owner_before(weak_ptr const& b) const { + bool owner_before(std::weak_ptr const& b) const { return true; /* FIXME - use non-det */ } }; + template inline bool operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) noexcept { @@ -229,8 +248,8 @@ inline bool operator!=(const shared_ptr<_Tp>& __x, 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()); + typedef typename std::common_type<_Tp*, _Up*>::type _Vp; + return std::less<_Vp>()(__x.get(), __y.get()); } template @@ -252,64 +271,71 @@ inline bool operator>=(const shared_ptr<_Tp>& __x, } template -inline bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { +inline bool operator==(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { return !__x; } template -inline bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { +inline bool operator==(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept { return !__x; } template -inline bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { +inline bool operator!=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { return static_cast(__x); } template -inline bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { +inline bool operator!=(std::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); +inline bool operator<(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { + return std::less<_Tp*>()(__x.get(), nullptr); } template -inline bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { - return less<_Tp*>()(nullptr, __x.get()); +inline bool operator<(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept { + return std::less<_Tp*>()(nullptr, __x.get()); } template -inline bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { +inline bool operator>(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { return nullptr < __x; } template -inline bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { +inline bool operator>(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept { return __x < nullptr; } template -inline bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { +inline bool operator<=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { return !(nullptr < __x); } template -inline bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { +inline bool operator<=(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept { return !(__x < nullptr); } template -inline bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) noexcept { +inline bool operator>=(const shared_ptr<_Tp>& __x, std::nullptr_t) noexcept { return !(__x < nullptr); } template -inline bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) noexcept { +inline bool operator>=(std::nullptr_t, const shared_ptr<_Tp>& __x) noexcept { return !(nullptr < __x); } +} // namespace infer_std_model + +INFER_NAMESPACE_STD_BEGIN + +// make std::shared_ptr alias of infer_std_model::shared_ptr +template +using shared_ptr = infer_std_model::shared_ptr; template struct hash> : public hash> {}; diff --git a/infer/models/cpp/include/infer_model/unique_ptr.h b/infer/models/cpp/include/infer_model/unique_ptr.h index 6464cc6b2..774d7225a 100644 --- a/infer/models/cpp/include/infer_model/unique_ptr.h +++ b/infer/models/cpp/include/infer_model/unique_ptr.h @@ -11,12 +11,14 @@ #include -INFER_NAMESPACE_STD_BEGIN +// define unique_ptr outside of std namespace. It will be aliased as +// std::unique_ptr via 'using' clause later +namespace infer_std_model { // IMPORTANT // There is specialization of unique_ptr below and it's mosly copy paste. // When changing model, remember to change it for specialization as well! -template > +template struct unique_ptr { // use SFINAE to determine whether _Del::pointer exists class _Pointer { @@ -26,7 +28,7 @@ struct unique_ptr { template static _Tp* __test(...); - typedef typename remove_reference<_Dp>::type _Del; + typedef typename std::remove_reference<_Dp>::type _Del; public: typedef decltype(__test<_Del>(0)) type; @@ -39,44 +41,45 @@ struct unique_ptr { pointer data; template - unique_ptr(const std__unique_ptr& u) {} + unique_ptr(const std::std__unique_ptr& u) {} constexpr unique_ptr() noexcept : data(nullptr) {} - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr<_Tp, _Dp>() {} + constexpr unique_ptr(std::nullptr_t) noexcept : unique_ptr<_Tp, _Dp>() {} explicit unique_ptr(pointer ptr) : data(ptr) {} unique_ptr(pointer ptr, - typename conditional< - is_reference::value, - deleter_type, - typename add_lvalue_reference::type>::type - __d) noexcept : data(ptr) {} + typename std::conditional< + std::is_reference::value, + deleter_type, + typename std::add_lvalue_reference::type>::type + __d) noexcept : data(ptr) {} unique_ptr(pointer ptr, - typename remove_reference::type&& __d) noexcept + typename std::remove_reference::type&& __d) noexcept : data(ptr) {} unique_ptr(unique_ptr&& u) noexcept : data(u.data) { u.data = nullptr; } template ::value && - is_convertible::pointer, - pointer>::value && - is_convertible<_Ep, deleter_type>::value && - (!is_reference::value || - is_same::value)>::type> + typename = typename std::enable_if< + !std::is_array<_Up>::value && + std::is_convertible::pointer, + pointer>::value && + std::is_convertible<_Ep, deleter_type>::value && + (!std::is_reference::value || + std::is_same::value)>::type> unique_ptr(unique_ptr<_Up, _Ep>&& u) noexcept : data(u.data) { u.data = nullptr; } template < class _Up, - typename = typename enable_if::value>::type> - unique_ptr(auto_ptr<_Up>&& __p) noexcept; + typename = typename std::enable_if< + std::is_convertible<_Up*, _Tp*>::value>::type> + unique_ptr(std::auto_ptr<_Up>&& __p) noexcept; ~unique_ptr() { reset(); } @@ -87,28 +90,30 @@ struct unique_ptr { template ::value && - is_convertible::pointer, - pointer>::value && - is_assignable::value>::type> + typename = typename std::enable_if< + !std::is_array<_Up>::value && + std::is_convertible::pointer, + pointer>::value && + std::is_assignable::value>::type> unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.data); return *this; } - unique_ptr& operator=(nullptr_t) noexcept { + unique_ptr& operator=(std::nullptr_t) noexcept { reset(); return *this; } - typename add_lvalue_reference<_Tp>::type operator*() const { return *data; } + typename std::add_lvalue_reference<_Tp>::type operator*() const { + return *data; + } pointer operator->() const { return data; } pointer get() const { return data; } - typedef typename remove_reference::type& _Dp_reference; - typedef const typename remove_reference::type& + typedef typename std::remove_reference::type& _Dp_reference; + typedef const typename std::remove_reference::type& _Dp_const_reference; _Dp_const_reference get_deleter() const {} _Dp_reference get_deleter() {} @@ -135,7 +140,7 @@ struct unique_ptr<_Tp[], _Dp> { template static _Tp* __test(...); - typedef typename remove_reference<_Dp>::type _Del; + typedef typename std::remove_reference<_Dp>::type _Del; public: typedef decltype(__test<_Del>(0)) type; @@ -150,40 +155,42 @@ struct unique_ptr<_Tp[], _Dp> { constexpr unique_ptr() noexcept : data(nullptr) {} - constexpr unique_ptr(nullptr_t) noexcept : data(nullptr) {} + constexpr unique_ptr(std::nullptr_t) noexcept : data(nullptr) {} explicit unique_ptr(pointer ptr) : data(ptr) {} unique_ptr( pointer ptr, - typename conditional< - is_reference::value, - deleter_type, - typename add_lvalue_reference::type>::type __d) + typename std::conditional::value, + deleter_type, + typename std::add_lvalue_reference< + const deleter_type>::type>::type __d) : data(ptr) {} - unique_ptr(pointer ptr, typename remove_reference::type&& __d) + unique_ptr(pointer ptr, + typename std::remove_reference::type&& __d) : data(ptr) {} unique_ptr(unique_ptr&& u) : data(u.data) { u.data = nullptr; } template ::value && - is_convertible::pointer, - pointer>::value && - is_convertible<_Ep, deleter_type>::value && - (!is_reference::value || - is_same::value)>::type> + typename = typename std::enable_if< + std::is_array<_Up>::value && + std::is_convertible::pointer, + pointer>::value && + std::is_convertible<_Ep, deleter_type>::value && + (!std::is_reference::value || + std::is_same::value)>::type> unique_ptr(unique_ptr<_Up, _Ep>&& u) : data(u.data) { u.data = nullptr; } template < class _Up, - typename = typename enable_if::value>::type> - unique_ptr(auto_ptr<_Up>&& __p) noexcept; + typename = typename std::enable_if< + std::is_convertible<_Up*, _Tp*>::value>::type> + unique_ptr(std::auto_ptr<_Up>&& __p) noexcept; ~unique_ptr() { reset(); } @@ -194,27 +201,27 @@ struct unique_ptr<_Tp[], _Dp> { template ::value && - is_convertible::pointer, - pointer>::value && - is_assignable::value>::type> + typename = typename std::enable_if< + std::is_array<_Up>::value && + std::is_convertible::pointer, + pointer>::value && + std::is_assignable::value>::type> unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) { reset(__u.data); return *this; } - unique_ptr& operator=(nullptr_t) { + unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } - typename add_lvalue_reference<_Tp>::type operator[](size_t i) const {} + typename std::add_lvalue_reference<_Tp>::type operator[](size_t i) const {} pointer get() const { return data; } - typedef typename remove_reference::type& _Dp_reference; - typedef const typename remove_reference::type& + typedef typename std::remove_reference::type& _Dp_reference; + typedef const typename std::remove_reference::type& _Dp_const_reference; _Dp_const_reference get_deleter() const {} _Dp_reference get_deleter() {} @@ -271,66 +278,74 @@ inline bool operator>=(const unique_ptr<_T1, _D1>& __x, } template -inline bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator==(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { return !__x; } template -inline bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator==(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !__x; } template -inline bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator!=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { return static_cast(__x); } template -inline bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator!=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { return static_cast(__x); } template -inline bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator<(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { /*typedef typename unique_ptr<_T1, _D1>::pointer _P1; return less<_P1>()(__x.get(), nullptr);*/ } template -inline bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator<(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { /*typedef typename unique_ptr<_T1, _D1>::pointer _P1; return less<_P1>()(nullptr, __x.get());*/ } template -inline bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator>(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { return nullptr < __x; } template -inline bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator>(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { return __x < nullptr; } template -inline bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator<=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { return !(nullptr < __x); } template -inline bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator<=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !(__x < nullptr); } template -inline bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { +inline bool operator>=(const unique_ptr<_T1, _D1>& __x, std::nullptr_t) { return !(__x < nullptr); } template -inline bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { +inline bool operator>=(std::nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !(nullptr < __x); } +} // namespace infer_std_model + +INFER_NAMESPACE_STD_BEGIN + +// make std::unique_ptr alias of infer_std_model::unique_ptr +template > +using unique_ptr = infer_std_model::unique_ptr<_Tp, _Dp>; + template struct hash> : public hash> { diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index 3edc774f6..adfa7eb9a 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -17,8 +17,8 @@ module F = Format module DExp = DecompiledExp let smart_pointers = [ - ["std"; "shared_ptr"]; - ["std"; "unique_ptr"] + ["infer_std_model"; "shared_ptr"]; + ["infer_std_model"; "unique_ptr"] ] let pointer_wrapper_classes = smart_pointers