Improve insert/emplace robustness to self insertion
Jonathan Wakely
jwakely@redhat.com
Wed Jun 29 08:57:00 GMT 2016
On 28/06/16 21:59 +0200, François Dumont wrote:
> template<typename _Tp, typename _Alloc>
> void
> vector<_Tp, _Alloc>::
>- _M_insert_aux(iterator __position, const _Tp& __x)
>+ _M_insert_value_aux(iterator __position, const _Tp& __x)
> #endif
> {
>- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
>+ const _Tp* __ptr = std::__addressof(__x);
>+
>+ _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
>+ _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1)));
>+ ++this->_M_impl._M_finish;
>+
>+ _GLIBCXX_MOVE_BACKWARD3(__position.base(),
>+ this->_M_impl._M_finish - 2,
>+ this->_M_impl._M_finish - 1);
>+
>+ if (_M_data_ptr(__position.base()) <= __ptr
>+ && __ptr < _M_data_ptr(this->_M_impl._M_finish - 1))
This is undefined behaviour. If the object is not contained in the
vector then you can't compare its address to addresses within the
vector.
I suggest forgetting about this optimisation unless we get a guarantee
from the compiler that we can do it safely. It's orthogonal to fixing
the correctness bug with emplacing an existing element of the vector.
We can fix the correctness bug now and worry about this optimisation
separately.
More information about the Libstdc++
mailing list