Improve insert/emplace robustness to self insertion

François Dumont frs.dumont@gmail.com
Wed Jun 29 19:43:00 GMT 2016


On 29/06/2016 11:10, Jonathan Wakely wrote:
> On 28/06/16 21:59 +0200, François Dumont wrote:
>> @@ -303,16 +301,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>>       emplace(const_iterator __position, _Args&&... __args)
>>       {
>>     const size_type __n = __position - begin();
>
> It looks like this should use __position - cbegin(), to avoid an
> implicit conversion from iterator to const_iterator, and ...
>
>> -    if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
>> -        && __position == end())
>> -      {
>> -        _Alloc_traits::construct(this->_M_impl, 
>> this->_M_impl._M_finish,
>> -                     std::forward<_Args>(__args)...);
>> -        ++this->_M_impl._M_finish;
>> -      }
>> +    if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
>> +      if (__position == end())
>
> This could be __position == cend(), and ...
>
>> +        {
>> +          _Alloc_traits::construct(this->_M_impl, 
>> this->_M_impl._M_finish,
>> +                       std::forward<_Args>(__args)...);
>> +          ++this->_M_impl._M_finish;
>> +        }
>> +      else
>> +        _M_insert_aux(begin() + (__position - cbegin()),
>
> This could use __n, and ...
>
>> + std::forward<_Args>(__args)...);
>>     else
>> -      _M_insert_aux(begin() + (__position - cbegin()),
>> -            std::forward<_Args>(__args)...);
>> +      _M_realloc_insert_aux(begin() + (__position - cbegin()),
>
> This could also use __n.
>
>> + std::forward<_Args>(__args)...);
>> +
>>     return iterator(this->_M_impl._M_start + __n);
>>       }
>>
> .
>
I tried those changes too but started having failing tests in 
vector/ext_pointer so prefer to not touch that for the moment. I think 
the compilation error was coming from the change of begin() + 
(__position - cbegin()) into begin() + __n because of overloaded 
operator+. The 2 other changes should be fine for a future patch.

As asked here is now a patch to only fix the robustness issue. The 
consequence is that it is reverting the latest optimization as, without 
smart algo, we always need to do a copy to protect against insertion of 
values contained in the vector as shown by new tests.

François
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vector_self_insert.patch
Type: text/x-patch
Size: 14995 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20160629/652abe8c/attachment.bin>


More information about the Libstdc++ mailing list