[Bug libstdc++/66742] abort on sorting list with custom allocator that is not stateless
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Oct 1 19:40:08 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66742
--- Comment #16 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:
https://gcc.gnu.org/g:ff7793bea465019683b3a07d7ffceb6eae22def5
commit r12-4082-gff7793bea465019683b3a07d7ffceb6eae22def5
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue May 25 14:33:15 2021 +0100
libstdc++: Allow stateful allocators in std::list::sort [PR 66742]
The temporary lists used by std::list::sort are default constructed,
which means they use default constructed allocators. The sort operation
is defined in terms of merge and splice operations, which have undefined
behaviour (and abort) if the allocators do not compare equal. This means
it is not possible to sort a list that uses an allocator that compares
unequal to an default constructed allocator.
The solution is to avoid using temporary std::list objects at all. We do
not need to be able to allocate memory because no nodes are allocated,
only spliced from one list to another. That means the temporary lists
don't need an allocator at all, so whether it would compare equal
doesn't matter.
Instead of temporary std::list objects, we can just use a collection of
_List_node_base objects that nodes can be spliced onto as needed. Those
objects are wrapped in a _Scratch_list type that implements the splicing
and merging operations used by list::sort.
We also don't need to update the list size during the sort, because
sorting doesn't alter the number of nodes. Although we move nodes in and
out of the scratch lists, at the end of the function all nodes are back
in the original std::list and the scratch lists are empty. So for the
cxx11 ABI we can avoid the _M_size modifications usually done when
splicing nodes.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
PR libstdc++/66742
* include/bits/list.tcc (list::sort()): Use _Scratch_list
objects for splicing and merging.
(list::sort(StrictWeakOrdering)): Likewise.
* include/bits/stl_list.h (__detail::_Scratch_list): New type.
* src/c++98/list.cc (_List_node_base::_M_transfer): Add
assertion for --enable-libstdcxx-debug library.
* testsuite/23_containers/list/operations/66742.cc: New test.
More information about the Gcc-bugs
mailing list