From: Jonathan Wakely Date: Wed, 30 Oct 2024 11:41:47 +0000 (+0000) Subject: libstdc++: More user-friendly failed assertions from shared_ptr dereference X-Git-Tag: basepoints/gcc-16~4574 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b169ee7e25129fede3aadbeb72037017d1d5a47;p=thirdparty%2Fgcc.git libstdc++: More user-friendly failed assertions from shared_ptr dereference Currently dereferencing an empty shared_ptr prints a complicated internal type in the assertion message: include/bits/shared_ptr_base.h:1377: std::__shared_ptr_access<_Tp, _Lp, , >::element_type& std::__shared_ptr_access<_Tp, _Lp, , >::operator*() const [with _Tp = std::filesystem::__cxx11::recursive_directory_iterator::_Dir_stack; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic; bool = false; bool = false; element_type = std::filesystem::__cxx11::recursive_directory_iterator::_Dir_stack]: Assertion '_M_get() != nullptr' failed. Users don't care about any of the _Lp and template parameters, so this is unnecessarily verbose. We can simplify it to something that only mentions "shared_ptr_deref" and the element type: include/bits/shared_ptr_base.h:1371: _Tp* std::__shared_ptr_deref(_Tp*) [with _Tp = filesystem::__cxx11::recursive_directory_iterator::_Dir_stack]: Assertion '__p != nullptr' failed. libstdc++-v3/ChangeLog: * include/bits/shared_ptr_base.h (__shared_ptr_deref): New function template. (__shared_ptr_access, __shared_ptr_access<>): Use it. --- diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 9a7617e7014f..ee01594ce0c5 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1337,6 +1337,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; + template + [[__gnu__::__always_inline__]] + inline _Tp* + __shared_ptr_deref(_Tp* __p) + { + __glibcxx_assert(__p != nullptr); + return __p; + } + // Define operator* and operator-> for shared_ptr. template::value, bool = is_void<_Tp>::value> @@ -1347,10 +1356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type& operator*() const noexcept - { - __glibcxx_assert(_M_get() != nullptr); - return *_M_get(); - } + { return *std::__shared_ptr_deref(_M_get()); } element_type* operator->() const noexcept @@ -1392,10 +1398,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[__deprecated__("shared_ptr::operator* is absent from C++17")]] element_type& operator*() const noexcept - { - __glibcxx_assert(_M_get() != nullptr); - return *_M_get(); - } + { return *std::__shared_ptr_deref(_M_get()); } [[__deprecated__("shared_ptr::operator-> is absent from C++17")]] element_type* @@ -1406,13 +1409,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" element_type& operator[](ptrdiff_t __i) const noexcept { - __glibcxx_assert(_M_get() != nullptr); - __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); - return _M_get()[__i]; + if constexpr (extent<_Tp>::value) + __glibcxx_assert(__i < extent<_Tp>::value); + return std::__shared_ptr_deref(_M_get())[__i]; } +#pragma GCC diagnostic pop private: element_type*