This is a conservative implementation of a patch to make shared/unique_ptrs behave more like plain old pointers. More about this in bug #88738
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88738 The summary is - using clang, which enables a warning for unused results of all comparison operation, found a real bug - a library implementation is limited in scope and tedious to add everywhere. At this stage of gcc 9 it was the only acceptable solution, though - longer term there should be a warning for comparison operators. Possibly on by default with the possibility to disable it with an attribute (see the discussion in the bug). The patch proposed here only changes the code for C++17 and up to use the [[nodiscard]] attribute. For gcc 10 we can either widen this or implement a better way with the help of the compiler. I ran the regression test suite and didn't see any additional failures. OK? libstdc++-v3/ 2019-02-14 Ulrich Drepper <drep...@redhat.com> PR libstdc++/88738 Warn about unused comparisons of shared_ptr/unique_ptr * include/bits/c++config [_GLIBCXX_NODISCARD]: Define. * include/bits/shared_ptr.h: Use it for operator ==, !=, <, <=, >, >= for shared_ptr. * include/bits/unique_ptr.h: Likewise for unique_ptr.
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 9b2fabd7d76..97bb6db70b1 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -99,6 +99,14 @@ # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) #endif +// Macro to warn about unused results. +#if __cplusplus >= 201703L +# define _GLIBCXX_NODISCARD [[__nodiscard__]] +#else +# define _GLIBCXX_NODISCARD +#endif + + #if __cplusplus diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 99009ab4f99..d504627d1a0 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -380,37 +380,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.7.2.2.7 shared_ptr comparisons template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return __a.get() == __b.get(); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !__a; } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !__a; } template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return __a.get() != __b.get(); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return (bool)__a; } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return (bool)__a; } template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; @@ -420,7 +420,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; @@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; @@ -436,47 +436,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return !(__b < __a); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !(nullptr < __a); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !(__a < nullptr); } template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return (__b < __a); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return nullptr < __a; } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return __a < nullptr; } template<typename _Tp, typename _Up> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return !(__a < __b); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !(__a < nullptr); } template<typename _Tp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !(nullptr < __a); } diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index c7eb02e86fd..61a3ef05460 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -707,41 +707,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return __x.get() == __y.get(); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept { return !__x; } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept { return !__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return __x.get() != __y.get(); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept { return (bool)__x; } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept { return (bool)__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { @@ -752,67 +752,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), nullptr); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, __x.get()); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return !(__y < __x); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return !(nullptr < __x); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return !(__x < nullptr); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return (__y < __x); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, __x.get()); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), nullptr); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return !(__x < __y); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return !(__x < nullptr); } template<typename _Tp, typename _Dp> - inline bool + _GLIBCXX_NODISCARD inline bool operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return !(nullptr < __x); }
signature.asc
Description: OpenPGP digital signature