aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2022-03-10 14:17:03 +0000
committerJonathan Wakely <jwakely@redhat.com>2022-03-10 14:25:46 +0000
commit73f3b8a53e6664c079731c2a183c16621481d039 (patch)
tree2699289256ab4cb281f0c9c534a3c1d0a8fb1713
parentc65d3c7f9dade18826d1a28d71b98c7cdc3e4300 (diff)
downloadgcc-73f3b8a53e6664c079731c2a183c16621481d039.zip
gcc-73f3b8a53e6664c079731c2a183c16621481d039.tar.gz
gcc-73f3b8a53e6664c079731c2a183c16621481d039.tar.bz2
libstdc++: Fix std::strong_order to handle NaN on VAX
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.
-rw-r--r--libstdc++-v3/libsupc++/compare12
1 files changed, 10 insertions, 2 deletions
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 3c22d9a..6e1ed53 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -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);