[committed] libstdc++: Fix regression in std::list::sort [PR66742]

Message ID 20211103165148.1788896-1-jwakely@redhat.com
State Committed
Commit 1e7a269856fd67aff78ac874bec96d31a54b2fd9
Headers
Series [committed] libstdc++: Fix regression in std::list::sort [PR66742] |

Commit Message

Jonathan Wakely Nov. 3, 2021, 4:51 p.m. UTC
  The standard does not require const-correct comparisons in list::sort.

Tested powerpc64le-linux, committed to trunk.


libstdc++-v3/ChangeLog:

	PR libstdc++/66742
	* include/bits/list.tcc (list::sort): Use mutable iterators for
	comparisons.
	* include/bits/stl_list.h (_Scratch_list::_Ptr_cmp): Likewise.
	* testsuite/23_containers/list/operations/66742.cc: Check
	non-const comparisons.
---
 libstdc++-v3/include/bits/list.tcc            |  4 ++--
 libstdc++-v3/include/bits/stl_list.h          |  8 +++----
 .../23_containers/list/operations/66742.cc    | 23 +++++++++++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)
  

Patch

diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index 7f4e1569ab1..cc750c98a2d 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -499,7 +499,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	_Scratch_list* __fill = __tmp;
 	_Scratch_list* __counter;
 
-	_Scratch_list::_Ptr_cmp<const_iterator, void> __ptr_comp;
+	_Scratch_list::_Ptr_cmp<iterator, void> __ptr_comp;
 
 	__try
 	  {
@@ -623,7 +623,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  _Scratch_list* __fill = __tmp;
 	  _Scratch_list* __counter;
 
-	_Scratch_list::_Ptr_cmp<const_iterator, _StrictWeakOrdering> __ptr_comp
+	_Scratch_list::_Ptr_cmp<iterator, _StrictWeakOrdering> __ptr_comp
 	  = { __comp };
 
 	  __try
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 96d2a2f0f69..ffaaa6dfd97 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -174,8 +174,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  _Cmp _M_cmp;
 
 	  bool
-	  operator()(const __detail::_List_node_base* __lhs,
-		     const __detail::_List_node_base* __rhs) /* not const */
+	  operator()(__detail::_List_node_base* __lhs,
+		     __detail::_List_node_base* __rhs) /* not const */
 	  { return _M_cmp(*_Iter(__lhs), *_Iter(__rhs)); }
 	};
 
@@ -183,8 +183,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	struct _Ptr_cmp<_Iter, void>
 	{
 	  bool
-	  operator()(const __detail::_List_node_base* __lhs,
-		     const __detail::_List_node_base* __rhs) const
+	  operator()(__detail::_List_node_base* __lhs,
+		     __detail::_List_node_base* __rhs) const
 	  { return *_Iter(__lhs) < *_Iter(__rhs); }
 	};
 
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/66742.cc b/libstdc++-v3/testsuite/23_containers/list/operations/66742.cc
index 24bda3920d8..94a37a31de7 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/66742.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/66742.cc
@@ -48,8 +48,31 @@  test01()
   VERIFY( is_sorted(l, std::greater<int>()) );
 }
 
+void
+test02()
+{
+  // The standard doesn't require comparisons to be const-correct.
+  // The initial fix for PR 66742 caused a regression here.
+
+  struct X
+  {
+    bool operator<(X&) /* non-const */ { return false; }
+  };
+
+  struct Cmp
+  {
+    bool operator()(X&, X&) /* non-const */ { return false; }
+  };
+
+  std::list<X> l;
+  l.sort();
+  Cmp c;
+  l.sort(c);
+}
+
 int
 main()
 {
   test01();
+  test02();
 }