https://gcc.gnu.org/g:fcb3009a32dc33906934a2360e556dfeb98980cf

commit r16-3414-gfcb3009a32dc33906934a2360e556dfeb98980cf
Author: Tomasz Kamiński <tkami...@redhat.com>
Date:   Tue Aug 26 14:34:35 2025 +0200

    libsupc++: Change _Unordered comparison value to minimum value of signed 
char.
    
    For any minimum value of a signed type, its negation (with wraparound) 
results
    in the same value, behaving like zero. Representing the unordered result 
with
    this minimum value, along with 0 for equal, 1 for greater, and -1 for less
    in partial_ordering, allows its value to be reversed using unary negation.
    
    The operator<=(partial_order, 0) now checks if the reversed value is 
positive.
    This works correctly because the unordered value remains unchanged and thus
    negative.
    
    libstdc++-v3/ChangeLog:
    
            * libsupc++/compare (_Ncmp::_Unordered): Rename and change the value
            to minimum value of signed char.
            (_Ncomp::unordered): Renamed from _Unordered, the name is reserved
            by partial_ordered::unordered.
            (partial_ordering::_M_reverse()): Define.
            (operator<=(partial_ordering, __cmp_cat::__unspec))
            (operator>=(__cmp_cat::__unspec, partial_ordering)): Implemented
            in terms of negated _M_value.
            (operator>=(partial_ordering, __cmp_cat::__unspec))
            (operator<=(__cmp_cat::__unspec, partial_ordering)): Directly
            compare _M_value, as unordered value is negative.
            (partial_ordering::unordered): Handle _Ncmp::unoredred rename.
            * python/libstdcxx/v6/printers.py: Add -128 as integer value
            for unordered, keeping 2 to preserve backward compatibility.
    
    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    Signed-off-by: Tomasz Kamiński <tkami...@redhat.com>

Diff:
---
 libstdc++-v3/libsupc++/compare               | 22 +++++++++++++++-------
 libstdc++-v3/python/libstdcxx/v6/printers.py |  6 +++++-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 82b5c53139c9..2624fa9144fb 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -56,7 +56,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 
     enum class _Ord : type { equivalent = 0, less = -1, greater = 1 };
 
-    enum class _Ncmp : type { _Unordered = 2 };
+    enum class _Ncmp : type { unordered = -__SCHAR_MAX__ - 1 };
 
     struct __unspec
     {
@@ -66,7 +66,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 
   class partial_ordering
   {
-    // less=0xff, equiv=0x00, greater=0x01, unordered=0x02
+    // less=0xff, equiv=0x00, greater=0x01, unordered=0x80
     __cmp_cat::type _M_value;
 
     constexpr explicit
@@ -82,6 +82,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
     friend class weak_ordering;
     friend class strong_ordering;
 
+    [[__gnu__::__always_inline__]]
+    constexpr __cmp_cat::type
+    _M_reverse() const
+    {
+      // leaves _Ncmp::unordered unchanged
+      return static_cast<__cmp_cat::type>(-_M_value);
+    }
+
   public:
     // valid values
     static const partial_ordering less;
@@ -112,12 +120,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
     [[nodiscard]]
     friend constexpr bool
     operator<=(partial_ordering __v, __cmp_cat::__unspec) noexcept
-    { return __v._M_value <= 0; }
+    { return __v._M_reverse() >= 0; }
 
     [[nodiscard]]
     friend constexpr bool
     operator>=(partial_ordering __v, __cmp_cat::__unspec) noexcept
-    { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+    { return __v._M_value >= 0; }
 
     [[nodiscard]]
     friend constexpr bool
@@ -132,12 +140,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
     [[nodiscard]]
     friend constexpr bool
     operator<=(__cmp_cat::__unspec, partial_ordering __v) noexcept
-    { return __cmp_cat::type(__v._M_value & 1) == __v._M_value; }
+    { return 0 <= __v._M_value; }
 
     [[nodiscard]]
     friend constexpr bool
     operator>=(__cmp_cat::__unspec, partial_ordering __v) noexcept
-    { return 0 >= __v._M_value; }
+    { return 0 <= __v._M_reverse(); }
 
     [[nodiscard]]
     friend constexpr partial_ordering
@@ -166,7 +174,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
   partial_ordering::greater(__cmp_cat::_Ord::greater);
 
   inline constexpr partial_ordering
-  partial_ordering::unordered(__cmp_cat::_Ncmp::_Unordered);
+  partial_ordering::unordered(__cmp_cat::_Ncmp::unordered);
 
   class weak_ordering
   {
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 5f5963cb5954..e5336b7fa89b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1749,7 +1749,11 @@ class StdCmpCatPrinter(printer_base):
         if self._typename == 'strong_ordering' and self._val == 0:
             name = 'equal'
         else:
-            names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'}
+            names = {
+                -1: 'less', 0: 'equivalent', 1: 'greater',
+                # GCC 10-15 used 2 for unordered
+                -128: 'unordered', 2: 'unordered'
+            }
             name = names[int(self._val)]
         return 'std::{}::{}'.format(self._typename, name)

Reply via email to