https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115413
--- Comment #3 from user202729 <user202729 at protonmail dot com> --- (In reply to Jason Merrill from comment #2) > If you're going to write code like this, why not > > if(typeid(*a)==typeid(A)) a->A::f(); > > to force the non-virtual call? The practical reason is that that was inspired from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110057 . The knowledge of the object's runtime type and the virtual function call are at different levels, and only the optimizer can inline the function. I can't think of any better way to address the issue, and I don't think the optimization generates incorrect code anyway. An idea I had was: --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -1325,7 +1325,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { __glibcxx_requires_nonempty(); --this->_M_impl._M_finish; - _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + + if (std::is_same<std::allocator<_Tp>, _Alloc>::value) { + this->_M_impl._M_finish->_Tp::~_Tp(); + } else { + _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + } + _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); } but that only works for std::allocator, and it is also incorrect (the user can partially specialize std::allocator as well: https://stackoverflow.com/q/61151170)