libstdc++: Fix std::strong_order to handle NaN on VAX
authorJonathan Wakely <jwakely@redhat.com>
Thu, 10 Mar 2022 14:17:03 +0000 (14:17 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 10 Mar 2022 14:25:46 +0000 (14:25 +0000)
I mistakenly believed that VAX floats do not support NaN, but with GCC
__builtin_isnan(__builtin_nan("")) is true. That means my previous
change to <compare> is wrong, because it fails to handle NaN.

When std::numeric_limits<floating-point-type>::is_iec559 is false, as on
VAX, the standard only requires an ordering that is consistent with the
ordering observed by comparison operators. With this change the ordering
is -NaN < numbers < +NaN, and there is no support for different NaN bit
patterns (as I'm not even sure if GCC supports any for VAX).

libstdc++-v3/ChangeLog:

* libsupc++/compare (_Strong_order::_S_fp_cmp) [__vax__]:
Handle NaN.

libstdc++-v3/libsupc++/compare

index 3c22d9a..6e1ed53 100644 (file)
@@ -844,8 +844,16 @@ namespace std
        _S_fp_cmp(_Tp __x, _Tp __y) noexcept
        {
 #ifdef __vax__
-         // VAX format has no NaN, only "excess" for Inf, so totally ordered.
-         return __builtin_bit_cast(strong_ordering, __x <=> __y);
+         if (__builtin_isnan(__x) || __builtin_isnan(__y))
+           {
+             int __ix = (bool) __builtin_isnan(__x);
+             int __iy = (bool) __builtin_isnan(__y);
+             __ix *= __builtin_signbit(__x) ? -1 : 1;
+             __iy *= __builtin_signbit(__y) ? -1 : 1;
+             return __ix <=> __iy;
+           }
+         else
+           return __builtin_bit_cast(strong_ordering, __x <=> __y);
 #endif
 
          auto __ix = _S_fp_bits(__x);