PR libstdc++/78420 Make std::less etc. yield total order for pointers
commitb6545b2d7df49f1d4343ecf86b6efd475e391915
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Mar 2018 23:02:01 +0000 (14 23:02 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Mar 2018 23:02:01 +0000 (14 23:02 +0000)
tree2cc7e822668858f2c90b9421515233ae9d9a32ca
parent8bb7c9b75598cc35c295b29262960d91283719a4
PR libstdc++/78420 Make std::less etc. yield total order for pointers

In order for std::less<T*> etc. to meet the total order requirements of
[comparisons] p2 we need to cast unrelated pointers to uintptr_t before
comparing them. Those casts aren't allowed in constant expressions, so
only cast when __builtin_constant_p says the result of the comparison is
not a compile-time constant (because the arguments are not constants, or
the result of the comparison is unspecified). When the result is
constant just compare the pointers directly without casting.

This ensures that the function can be called in constant expressions
with suitable arguments, but still yields a total order even for
otherwise unspecified pointer comparisons.

For std::less<void> etc. add new overloads for pointers, which use
std::less<common_type_t<T*,U*>> directly. Also change the generic
overloads to detect when the comparison would call a built-in relational
operator with pointer operands, and dispatch that case to the
corresponding specialization for void pointers.

PR libstdc++/78420
* include/bits/stl_function.h (greater<_Tp*>, less<_Tp*>)
(greater_equal<_Tp*>, less_equal<_Tp>*): Add partial specializations
to ensure total order for pointers.
(greater<void>, less<void>, greater_equal<void>, less_equal<void>):
Add operator() overloads for pointer arguments and make generic
overloads dispatch to new _S_cmp functions when comparisons would
use built-in operators for pointers.
* testsuite/20_util/function_objects/comparisons_pointer.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@258540 138bc75d-0d04-0410-961f-82ee72b054a4
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_function.h
libstdc++-v3/testsuite/20_util/function_objects/comparisons_pointer.cc [new file with mode: 0644]