https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110879
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- Ah I think that's probably expected. In _M_realloc_insert (and now _M_realloc_append) we have: #if __cplusplus >= 201103L if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) { // Relocation cannot throw. __new_finish = _S_relocate(__old_start, __position.base(), __new_start, _M_get_Tp_allocator()); ++__new_finish; __new_finish = _S_relocate(__position.base(), __old_finish, __new_finish, _M_get_Tp_allocator()); } else #endif and then an alternative path used for non-trivial types and for C++98. That alternative path does more work and probably can't be optimized as well, so the reads from _M_end_of_storage aren't optimized out. I think we can just use { target c++11 } for the test.