diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2025-09-11 17:39:43 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2025-09-12 21:46:51 +0100 |
commit | 7801236069a95ce13a968084463cdbbea8ce907a (patch) | |
tree | 9794c9115f2d732abc41f96513a2a91917e6256d | |
parent | 7b99d184bc9eada80992f7134c6c8e3b0eb0d19d (diff) | |
download | gcc-7801236069a95ce13a968084463cdbbea8ce907a.zip gcc-7801236069a95ce13a968084463cdbbea8ce907a.tar.gz gcc-7801236069a95ce13a968084463cdbbea8ce907a.tar.bz2 |
libstdc++: ranges::rotate should use ranges::iter_move [PR121913]
Using std::move(*it) is incorrect for iterators that use proxy refs, we
should use ranges::iter_move(it) instead.
libstdc++-v3/ChangeLog:
PR libstdc++/121913
* include/bits/ranges_algo.h (__rotate_fn::operator()): Use
ranges::iter_move(it) instead of std::move(*it).
* testsuite/25_algorithms/rotate/121913.cc: New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
-rw-r--r-- | libstdc++-v3/include/bits/ranges_algo.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/rotate/121913.cc | 45 |
2 files changed, 47 insertions, 2 deletions
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 609b82e..9b348d8 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -1685,7 +1685,7 @@ namespace ranges { auto __mid = ranges::next(__p, __n - 1); auto __end = ranges::next(__mid); - auto __t = std::move(*__p); + auto __t = ranges::iter_move(__p); ranges::move(ranges::next(__p), __end, __p); *__mid = std::move(__t); return {std::move(__ret), std::move(__lasti)}; @@ -1713,7 +1713,7 @@ namespace ranges { auto __mid = ranges::next(__p, __n - 1); auto __end = ranges::next(__mid); - auto __t = std::move(*__mid); + auto __t = ranges::iter_move(__mid); ranges::move_backward(__p, __mid, __end); *__p = std::move(__t); return {std::move(__ret), std::move(__lasti)}; diff --git a/libstdc++-v3/testsuite/25_algorithms/rotate/121913.cc b/libstdc++-v3/testsuite/25_algorithms/rotate/121913.cc new file mode 100644 index 0000000..d648699 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/rotate/121913.cc @@ -0,0 +1,45 @@ +// { dg-do compile { target c++20 } } + +// Bug libstdc++/121913 ranges::rotate should use ranges::iter_move + +#include <algorithm> + +struct A { }; + +struct B +{ + B& operator=(const B&) = delete; + B& operator=(const A&) const; + + operator A() const; +}; + +struct I +{ + using value_type = A; + using difference_type = int; + B operator*() const; + B operator[](int) const; + I& operator++(); + I operator++(int); + I& operator--(); + I operator--(int); + I& operator+=(int); + I& operator-=(int); + + auto operator<=>(const I&) const = default; + + friend A iter_move(const I&); + friend I operator+(I, int); + friend I operator-(I, int); + friend I operator+(int, I); + friend int operator-(I, I); +}; + +static_assert( std::random_access_iterator<I> ); + +void +test_pr121913() +{ + std::ranges::rotate(I{}, I{}, I{}); +} |