@@ -1325,7 +1325,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
__glibcxx_requires_nonempty();
--this->_M_impl._M_finish;
- _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
+ _Alloc_traits::_Destroy_static_type(this->_M_impl,
+ this->_M_impl._M_finish);
_GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
}
@@ -1870,7 +1871,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX20_CONSTEXPR
~_Temporary_value()
- { _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); }
+ { _Alloc_traits::_Destroy_static_type(_M_this->_M_impl, _M_ptr()); }
_GLIBCXX20_CONSTEXPR value_type&
_M_val() noexcept { return _M_storage._M_val; }
@@ -184,7 +184,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__position + 1 != end())
_GLIBCXX_MOVE3(__position + 1, end(), __position);
--this->_M_impl._M_finish;
- _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
+ _Alloc_traits::_Destroy_static_type(this->_M_impl,
+ this->_M_impl._M_finish);
_GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
return __position;
}
@@ -33,7 +33,7 @@
#pragma GCC system_header
#endif
-# include <bits/alloc_traits.h>
+#include <bits/alloc_traits.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
@@ -95,6 +95,30 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
noexcept(noexcept(_Base_type::destroy(__a, std::__to_address(__p))))
{ _Base_type::destroy(__a, std::__to_address(__p)); }
+ // Equivalent to `destroy` except that when `a.destroy(p)` is not valid,
+ // the destructor will be called using a qualified name, so that no
+ // dynamic dispatch to a virtual destructor is done. This can be used
+ // in e.g. std::vector where we know that the elements do not have a
+ // dynamic type that is different from the static type.
+ template<typename _Ptr>
+ [[__gnu__::__always_inline__]]
+ static _GLIBCXX20_CONSTEXPR void
+ _Destroy_static_type(_Alloc& __a, _Ptr __p)
+ {
+#if __cpp_concepts
+ auto __ptr = std::__to_address(__p);
+ if constexpr (requires { __a.destroy(__ptr); })
+ __a.destroy(__ptr);
+ else
+ {
+ using _Tp = std::remove_pointer_t<decltype(__ptr)>;
+ __ptr->_Tp::~_Tp();
+ }
+#else
+ destroy(__a, __p);
+#endif
+ }
+
[[__gnu__::__always_inline__]]
static constexpr _Alloc _S_select_on_copy(const _Alloc& __a)
{ return _Base_type::select_on_container_copy_construction(__a); }
@@ -178,6 +202,12 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
template<typename _Tp>
struct rebind
{ typedef typename _Alloc::template rebind<_Tp>::other other; };
+
+ template<typename _Ptr>
+ __attribute__((__always_inline__))
+ static void
+ _Destroy_static_type(_Alloc& __a, _Ptr __p)
+ { __a.destroy(__p); }
#endif // C++11
};