https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620
--- Comment #9 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #8) > That isn't necessarily true though. _S_check_init_len takes __n by non-const > reference and changes it to be the number of elements that are actually > allocated *which might be more than requested*. std::vector has to grow > exponentially, so if the current size is 10 and we ask for 12, it will > actually allocate space for 20, and set __n to 20. Oh I missed that and I am lucky I hadn't tested my proposed change yet. > So the end_of_storage is start + 20, but finish is start + 12 > > We could make a copy of __n before the call to _S_check_init_len, and then > use that: > > const size_type __orig_n = __n; > pointer __start = this->_M_impl._M_start = > this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator())); > this->_M_impl._M_end_of_storage = __start + __n; > this->_M_impl._M_finish > = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, > __start, _M_get_Tp_allocator()); > if (this->_M_impl._M_finish - this->_M_impl._M_start != __orig_n) > __builtin_unreachable(); I wonder if we should do something similar for _M_end_of_storage here with __n too? But maybe the optimizers can figure it out without any extra help. Though With if the type was a character type maybe __uninitialized_copy_a might cause the aliasing analysis not to be enough. (maybe that is for another time).