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

The standard does not require const-correct comparisons in list::sort.

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.
This commit is contained in:
Jonathan Wakely 2021-11-02 10:21:01 +00:00
parent 600dcd74b8
commit 1e7a269856
3 changed files with 29 additions and 6 deletions

View File

@ -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

View File

@ -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); }
};

View File

@ -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();
}