aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-09-11 17:39:43 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2025-09-12 21:46:51 +0100
commit7801236069a95ce13a968084463cdbbea8ce907a (patch)
tree9794c9115f2d732abc41f96513a2a91917e6256d
parent7b99d184bc9eada80992f7134c6c8e3b0eb0d19d (diff)
downloadgcc-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.h4
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/rotate/121913.cc45
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{});
+}