libstdc++: Make std::copy_n work with negative and non-integral sizes
authorJonathan Wakely <jwakely@redhat.com>
Thu, 4 Jun 2020 12:52:21 +0000 (13:52 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 4 Jun 2020 13:21:34 +0000 (14:21 +0100)
commite1008cd1d8504775e6a5e39325e396e61b39b84c
tree3df865cdfe150813345a81e41e68517808edce10
parenta3a70bf6690e310fb1d4afa4b3dd1b19ddd0e2f4
libstdc++: Make std::copy_n work with negative and non-integral sizes

Since it was added in C++11, std::copy_n and std::ranges::copy_n should
do nothing given a negative size, but for random access iterators we add
the size to the iterator, possibly resulting in undefined behaviour.

Also, C++20 clarified that std::copy_n requires the Size type to be
convertible to an integral type. We previously assumed that it could be
directly used in arithmetic expressions, without conversion to an
integral type.

This also fixes a bug in the random_access_iterator_wrapper helper adds
some convenience aliases for using the iterator wrappers.

libstdc++-v3/ChangeLog:

* include/bits/ranges_algobase.h (__copy_n_fn): Only call
ranges::copy for positive values.
* include/bits/stl_algo.h (copy_n): Convert Size argument to an
integral type and only call __copy_n for positive values.
* testsuite/util/testsuite_iterators.h
(random_access_iterator_wrapper::operator+=): Fix range check for
negative values.
(output_container, input_container, forward_container)
(bidirectional_container, random_access_container): New alias
templates.
* testsuite/25_algorithms/copy_n/5.cc: New test.
libstdc++-v3/include/bits/ranges_algobase.h
libstdc++-v3/include/bits/stl_algo.h
libstdc++-v3/testsuite/25_algorithms/copy_n/5.cc [new file with mode: 0644]
libstdc++-v3/testsuite/util/testsuite_iterators.h