Bug 58265 - [lwg/2063] std::string move assignment should be noexcept
Summary: [lwg/2063] std::string move assignment should be noexcept
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: 5.5
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-28 21:27 UTC by Frank Heckenbach
Modified: 2018-07-05 17:03 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-08-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Heckenbach 2013-08-28 21:27:15 UTC
According to http://www.cplusplus.com/reference/string/string/operator=/,
the std::string move assignment operator should be noexcept.

#include <string>
static_assert (std::is_nothrow_move_assignable <std::string>::value, "failed");
Comment 1 Paolo Carlini 2013-08-28 21:48:09 UTC
I'll fix this asap, very simple to do, but note that until we break the ABI basic_string will remain nonconforming in many serious ways.
Comment 2 Paolo Carlini 2013-08-28 21:57:41 UTC
As a matter of fact, isn't, in our current implementation, because std::swap itself isn't in case the allocators are not equal.

I can preliminarily adjust it for ext/vstring.h (a preview of the future c++11 conforming basic_string) but it still needs work as regards the C++11 memory allocation model.
Comment 3 Daniel Krügler 2013-08-31 10:21:54 UTC
Similar to containers the move-assignment operator of basic_string should not be noexcept, because they have a narrow contract. The fact that the specification currently requires this, is a defect. This is

http://cplusplus.github.io/LWG/lwg-active.html#2063
Comment 4 Paolo Carlini 2013-08-31 10:40:55 UTC
Thanks Daniel. I knew that we would have to revisit this anyway when the C++11 allocator model is implemented for the C++11 conforming basic_string. All in all, I guess better suspending this for the time being.

Since, as-is, the move assignment of ext/vstring is in fact noexcept, we may want to declare it as such however. By the way, I seem to remember that Jon has work almost ready for the C++11 conformance of it.
Comment 5 Marc Glisse 2013-09-20 15:50:12 UTC
Author: glisse
Date: Fri Sep 20 15:50:09 2013
New Revision: 202781

URL: http://gcc.gnu.org/viewcvs?rev=202781&root=gcc&view=rev
Log:
2013-09-20  Marc Glisse  <marc.glisse@inria.fr>

	PR libstdc++/58338
	* include/bits/allocator.h (__alloc_swap::_S_do_it,
	__shrink_to_fit_aux::_S_do_it): Mark as noexcept.
	* include/bits/basic_string.h (basic_string::_Rep) [_S_empty_rep,
	_M_is_leaked, _M_is_shared, _M_set_leaked, _M_set_sharable,
	_M_set_length_and_sharable, _M_dispose]: Likewise.
	(basic_string::_Alloc_hider::_Alloc_hider): Likewise.
	(basic_string) [_M_data, _M_rep, _M_ibegin, _M_iend, _M_limit,
	_M_disjunct, _M_copy, _M_move, _M_assign, _S_copy_chars, _S_compare,
	_S_empty_rep, shrink_to_fit, operator[] const, front const, back const]:
	Likewise.
	[clear]: Link to PR 56166.
	[swap]: Link to PR 58265.
	* include/bits/stl_deque.h (_Deque_iterator) [_S_buffer_size,
	_Deque_iterator, _M_const_cast, operator*, operator->, operator++,
	operator--, operator+=, operator+, operator-=, operator-, operator[],
	_M_set_node]: Mark as noexcept.
	(operator==(const _Deque_iterator&, const _Deque_iterator&),
	operator!=(const _Deque_iterator&, const _Deque_iterator&),
	operator<(const _Deque_iterator&, const _Deque_iterator&),
	operator>(const _Deque_iterator&, const _Deque_iterator&),
	operator<=(const _Deque_iterator&, const _Deque_iterator&),
	operator>=(const _Deque_iterator&, const _Deque_iterator&),
	operator-(const _Deque_iterator&, const _Deque_iterator&),
	operator+(ptrdiff_t, const _Deque_iterator&)): Likewise.
	(_Deque_base) [_Deque_base(const allocator_type&)]: Add missing call to
	_M_initialize_map.
	[~_Deque_base, _M_deallocate_node, _M_deallocate_map, _M_destroy_nodes]:
	Mark as noexcept.
	(_Deque_base::_Deque_impl) [_Deque_impl(const _Tp_alloc_type&),
	_Deque_impl(_Tp_alloc_type&&)]: Likewise.
	(deque) [_S_buffer_size, operator=(deque&&), shrink_to_fit, operator[],
	front, back, pop_front, pop_back, swap]: Likewise.
	[deque(), deque(const allocator_type&)]: Merge.
	* include/debug/deque (deque) [operator=(deque&&), shrink_to_fit,
	operator[], front, back, pop_front, pop_back, swap]: Mark as noexcept.
	* include/profile/deque (deque) [operator=(deque&&), operator[], front,
	back, pop_front, pop_back, swap]: Likewise.
	* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
	Adjust line number.
	* testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
	Likewise.
	* testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
	Likewise.
	* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
	Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/allocator.h
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/include/bits/stl_deque.h
    trunk/libstdc++-v3/include/debug/deque
    trunk/libstdc++-v3/include/profile/deque
    trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
Comment 6 Marc Glisse 2013-09-24 10:07:36 UTC
Author: glisse
Date: Tue Sep 24 10:07:32 2013
New Revision: 202861

URL: http://gcc.gnu.org/viewcvs?rev=202861&root=gcc&view=rev
Log:
2013-09-24  Marc Glisse  <marc.glisse@inria.fr>

	PR libstdc++/58338
	PR libstdc++/56166
	* include/bits/basic_string.h (basic_string)
	[basic_string(basic_string&&)]: Make the noexcept conditional.
	[operator=(basic_string&&), assign(basic_string&&)]: Link to PR 58265.
	[begin(), end(), rbegin(), rend(), clear]: Remove noexcept.
	[pop_back]: Comment on the lack of noexcept.
	* include/debug/string (basic_string) [basic_string(const _Allocator&),
	basic_string(basic_string&&), begin(), end(), rbegin(), rend(), clear,
	operator[](size_type), pop_back]: Comment out noexcept, until vstring
	replaces basic_string.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/include/debug/string
Comment 7 Antony Polukhin 2015-07-17 06:55:48 UTC
Wht's the status of this issue?

Issue still exists in GCC 5.1. Latest wording http://cplusplus.github.io/LWG/lwg-defects.html#2063 insists on making move assignment conditionally noexcept.
Comment 8 Jonathan Wakely 2015-07-17 11:14:05 UTC
I've been working on LWG2063 but forgot there was this PR for it.
Comment 9 Jonathan Wakely 2015-09-11 11:02:45 UTC
Author: redi
Date: Fri Sep 11 11:02:14 2015
New Revision: 227681

URL: https://gcc.gnu.org/viewcvs?rev=227681&root=gcc&view=rev
Log:
Implement N4258 noexcept for std::basic_string.

	PR libstdc++/58265
	* doc/xml/manual/intro.xml: Document LWG 2063 and 2064 resolutions.
	* doc/html/manual/bugs.html: Regenerate.
	* include/bits/basic_string.h (basic_string): Implement N4258. Add
	correct exception-specifications and propagate allocators correctly.
	* include/bits/basic_string.tcc (basic_string::swap): Propagate
	allocators correctly.
	* include/debug/string (__gnu_debug::basic_string): Add correct
	exceptions-specifications and allcoator-extended constructors.
	* testsuite/21_strings/basic_string/allocator/char/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/swap.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc: New.
	* testsuite/util/testsuite_allocator.h (tracker_allocator): Define
	defaulted assignment operators.

Added:
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/doc/html/manual/bugs.html
    trunk/libstdc++-v3/doc/xml/manual/intro.xml
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/include/bits/basic_string.tcc
    trunk/libstdc++-v3/include/debug/string
    trunk/libstdc++-v3/testsuite/util/testsuite_allocator.h
Comment 10 Jonathan Wakely 2015-09-11 11:03:16 UTC
Fixed on trunk.
Comment 11 Jonathan Wakely 2016-07-12 10:56:43 UTC
Author: redi
Date: Tue Jul 12 10:56:11 2016
New Revision: 238241

URL: https://gcc.gnu.org/viewcvs?rev=238241&root=gcc&view=rev
Log:
Implement N4258 noexcept for std::basic_string.

	Backport from mainline
	2015-10-02  Jonathan Wakely  <jwakely@redhat.com>

	* testsuite/21_strings/basic_string/allocator/char/minimal.cc: Guard
	explicit instantiation with check for new ABI.
	* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc:
	Likewise. Use wchar_t as char_type.

	Backport from mainline
	2015-09-11  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/58265
	* doc/xml/manual/intro.xml: Document LWG 2063 and 2064 resolutions.
	* doc/html/manual/bugs.html: Regenerate.
	* include/bits/basic_string.h (basic_string): Implement N4258. Add
	correct exception-specifications and propagate allocators correctly.
	* include/bits/basic_string.tcc (basic_string::swap): Propagate
	allocators correctly.
	* include/debug/string (__gnu_debug::basic_string): Add correct
	exceptions-specifications and allcoator-extended constructors.
	* testsuite/21_strings/basic_string/allocator/char/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/swap.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc: New.
	* testsuite/util/testsuite_allocator.h (tracker_allocator): Define
	defaulted assignment operators.

Added:
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc
Modified:
    branches/gcc-5-branch/libstdc++-v3/ChangeLog
    branches/gcc-5-branch/libstdc++-v3/doc/html/manual/bugs.html
    branches/gcc-5-branch/libstdc++-v3/doc/xml/manual/intro.xml
    branches/gcc-5-branch/libstdc++-v3/include/bits/basic_string.h
    branches/gcc-5-branch/libstdc++-v3/include/bits/basic_string.tcc
    branches/gcc-5-branch/libstdc++-v3/include/debug/string
    branches/gcc-5-branch/libstdc++-v3/testsuite/util/testsuite_allocator.h
Comment 12 Jonathan Wakely 2018-07-05 15:56:38 UTC
Author: redi
Date: Thu Jul  5 15:56:06 2018
New Revision: 262443

URL: https://gcc.gnu.org/viewcvs?rev=262443&root=gcc&view=rev
Log:
PR libstdc++/58265 implement LWG 2063 for COW strings

For COW strings the default constructor does not allocate when
_GLIBCXX_FULLY_DYNAMIC_STRING == 0, so can be noexcept. The move
constructor and swap do not allocate when the allocators are equal, so
add conditional noexcept using allocator_traits::is_always_equal.

	PR libstdc++/58265
	* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
	[_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()):
	Add GLIBCXX_NOEXCEPT.
	(basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF
	to depend on the allocator's is_always_equal property (LWG 2063).
	(basic_string::swap(basic_string&)): Likewise.
	* include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]
	(basic_string::swap(basic_string&)): Likewise.
	* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
	Check is_nothrow_move_assignable.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
	Check is_nothrow_move_assignable.
	* testsuite/21_strings/basic_string/cons/char/
	noexcept_move_construct.cc: Likewise.
	* testsuite/21_strings/basic_string/cons/wchar_t/
	noexcept_move_construct.cc: Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/include/bits/basic_string.tcc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/noexcept_move_construct.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/noexcept_move_construct.cc
Comment 13 Jonathan Wakely 2018-07-05 15:56:52 UTC
Now also fixed for COW strings.
Comment 14 Jonathan Wakely 2018-07-05 17:03:38 UTC
Author: redi
Date: Thu Jul  5 17:03:05 2018
New Revision: 262447

URL: https://gcc.gnu.org/viewcvs?rev=262447&root=gcc&view=rev
Log:
PR libstdc++/58265 add noexcept to basic_string::assign(basic_string&&)

	PR libstdc++/58265
	* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
	(basic_string::assign(basic_string&&)): Add conditional noexcept
	depending on the allocator's is_always_equal property (LWG 2063).
	* testsuite/21_strings/basic_string/modifiers/assign/char/
	move_assign.cc: Check for non-throwing exception specification.
	* testsuite/21_strings/basic_string/modifiers/assign/wchar_t/
	move_assign.cc: Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign.cc
    trunk/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign.cc