[PATCH] PR libstdc++/79254 fix exception-safety in std::string::operator=

Jonathan Wakely jwakely@redhat.com
Wed Feb 1 11:42:00 GMT 2017


On 27/01/17 16:16 +0000, Jonathan Wakely wrote:
>This implements the strong exception-safety guarantee that is required
>by [string.require] p2, which the new string can fail to meet when
>propagate_on_container_copy_assignment (POCCA) is true.
>
>The solution is to define a helper that takes ownership of the
>string's memory (and also the associated allocator, length and
>capacity) and either deallocates it after the assignment, or swaps it
>back in if an exception happens (i.e. commit or rollback).
>
>	PR libstdc++/79254
>	* config/abi/pre/gnu.ver: Add new symbols.
>	* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
>	(basic_string::_M_copy_assign): New overloaded functions to perform
>	copy assignment.
>	(basic_string::operator=(const basic_string&)): Dispatch to
>	_M_copy_assign.
>	* include/bits/basic_string.tcc [_GLIBCXX_USE_CXX11_ABI]
>	(basic_string::_M_copy_assign(const basic_string&, true_type)):
>	Define, performing rollback on exception.
>	* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
>	Test exception-safety guarantee.
>	* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
>	Likewise.
>	* testsuite/util/testsuite_allocator.h (uneq_allocator::swap): Make
>	std::swap visible.
>
>The backports for the branches will be a bit different, as we can't
>add new exports to closed symbol versions, so I'll keep everything in
>operator= instead of tag dispatching. The POCCA code path will still
>be dependent on a constant expression, so should be optimized away for
>most allocators.

Whlie working on the backport of this I realised the RAII
commit-and-rollback approach is a lot more complicated than simply
doing the new allocation before making any changes to *this.

This new patch simplifies it. There's no need to tag-dispatch to
_M_copy_assign because the code path for POCCA allocators is behind a
compile-time constant condition anyway, and the allocator assignment
is already conditional because of __alloc_on_copy.

******************************************************************
!!! This removes the new _M_copy_assign members functions that
!!! were exported from libstdc++.so since last Friday.
******************************************************************

Packagers (including at least Fedora rawhide) that have shipped a
gcc-7 build since last Friday will need to update again.  This
shouldn't be a big deal, because I expect the amount of code in a
typical GNU/Linux distro that used the _M_copy_assign(..., true_type)
symbol to be exactly zero, and the _M_copy_assign(..., false_type)
symbol will be inlined with any -Ox level, and is not used at -O0.

Tested powerpc64-linux, committed to trunk.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 7450 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20170201/40d44597/attachment.bin>


More information about the Libstdc++ mailing list