PR libstdc++/87749 fix (and optimize) string move construction
commit763276907a3b207eacbc7c85f89a1fc7655ca3db
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Oct 2018 15:34:04 +0000 (25 15:34 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Oct 2018 15:34:04 +0000 (25 15:34 +0000)
tree423414dc0da676e005efee425e91d2b2c97e265d
parent70657a4d7ad4f0036034776252c07a310d5d593a
PR libstdc++/87749 fix (and optimize) string move construction

The move constructor for the SSO string uses assign(const basic_string&)
when either:

(1) the source string is "local" and so the contents of the small string
buffer need to be copied, or

(2) the allocator does not propagate and is_always_equal is false.

Case (1) is suboptimal, because the assign member is not noexcept and
the compiler isn't smart enough to see it won't actually throw in this
case. This causes extra code in the move assignment operator so that any
exception will be turned into a call to std::terminate. This can be
fixed by copying small strings inline instead of calling assign.

Case (2) is a bug, because the specific instances of the allocators
could be equal even if is_always_equal is false. This can result in an
unnecessary deep copy (and potentially-throwing allocation) when the
storage should be moved. This can be fixed by simply checking if the
allocators are equal.

PR libstdc++/87749
* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
(basic_string::operator=(basic_string&&)): For short strings copy the
buffer inline. Only fall back to using assign(const basic_string&) to
do a deep copy when reallocation is needed.
* testsuite/21_strings/basic_string/modifiers/assign/char/87749.cc:
New test.
* testsuite/21_strings/basic_string/modifiers/assign/char/
move_assign_optim.cc: New test.
* testsuite/21_strings/basic_string/modifiers/assign/wchar_t/87749.cc:
New test.
* testsuite/21_strings/basic_string/modifiers/assign/wchar_t/
move_assign_optim.cc: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@265493 138bc75d-0d04-0410-961f-82ee72b054a4
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/87749.cc [new file with mode: 0644]
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign_optim.cc [new file with mode: 0644]
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/87749.cc [new file with mode: 0644]
libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign_optim.cc [new file with mode: 0644]