diff options
author | Patrick Palka <ppalka@redhat.com> | 2020-12-21 15:15:36 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2020-12-21 15:15:36 -0500 |
commit | 6a31d47e271d066ea85b3716f7b77f18e6b55242 (patch) | |
tree | 02684ce11cb6b5026d2c1cd62b7b753dd5d960f2 | |
parent | e798f081925b5085de3c9d0f330eb6e255a377bf (diff) | |
download | gcc-6a31d47e271d066ea85b3716f7b77f18e6b55242.zip gcc-6a31d47e271d066ea85b3716f7b77f18e6b55242.tar.gz gcc-6a31d47e271d066ea85b3716f7b77f18e6b55242.tar.bz2 |
libstdc++: Disable floating-point std::to_chars on unsupported targets
This patch conditionally disables the floating-point std::to_chars
implementation on targets whose float and double aren't IEEE binary32
and binary64, until a proper fallback can be added for such targets.
This fixes a bootstrap failure on non-IEEE-754 FP targets such as
vax-netbsdelf.
The new preprocessor tests in c++config that detect the binary32 and
binary64 formats were copied from gcc/testsuite/gcc.dg/float-exact-1.c.
libstdc++-v3/ChangeLog:
* include/bits/c++config (_GLIBCXX_FLOAT_IS_IEEE_BINARY_32):
Define this macro.
(_GLIBCXX_DOUBLE_IS_IEEE_BINARY_64): Likewise.
* include/std/charconv (to_chars): Use these macros to
conditionally hide the overloads for floating-point types.
* src/c++17/floating_to_chars.cc: Use the macros to
conditionally disable this file.
(floating_type_traits<float>): Remove redundant static assert.
(floating_type_traits<double>): Likewise.
* testsuite/20_util/to_chars/double.cc: Run this test only on
ieee-floats effective targets.
* testsuite/20_util/to_chars/float.cc: Likewise.
* testsuite/20_util/to_chars/long_double.cc: Likewise.
* testsuite/lib/libstdc++.exp
(check_effective_target_ieee-floats): Define new proc for
detecting whether float and double have the IEEE binary32 and
binary64 formats.
-rw-r--r-- | libstdc++-v3/include/bits/c++config | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/std/charconv | 2 | ||||
-rw-r--r-- | libstdc++-v3/src/c++17/floating_to_chars.cc | 10 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/to_chars/double.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/to_chars/float.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/to_chars/long_double.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/lib/libstdc++.exp | 8 |
7 files changed, 33 insertions, 4 deletions
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 8cce88a..be0961a 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -688,6 +688,20 @@ namespace std # endif #endif +// Define if float has the IEEE binary32 format. +#if __FLT_MANT_DIG__ == 24 \ + && __FLT_MIN_EXP__ == -125 \ + && __FLT_MAX_EXP__ == 128 +# define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1 +#endif + +// Define if double has the IEEE binary64 format. +#if __DBL_MANT_DIG__ == 53 \ + && __DBL_MIN_EXP__ == -1021 \ + && __DBL_MAX_EXP__ == 1024 +# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1 +#endif + #ifdef __has_builtin # ifdef __is_identifier // Intel and older Clang require !__is_identifier for some built-ins: diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index b57b0a1..c6e8069 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -702,6 +702,7 @@ namespace __detail chars_format __fmt = chars_format::general) noexcept; #endif +#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 // Floating-point std::to_chars // Overloads for float. @@ -725,6 +726,7 @@ namespace __detail chars_format __fmt) noexcept; to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision) noexcept; +#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/src/c++17/floating_to_chars.cc b/libstdc++-v3/src/c++17/floating_to_chars.cc index b7c31c7..6e15436 100644 --- a/libstdc++-v3/src/c++17/floating_to_chars.cc +++ b/libstdc++-v3/src/c++17/floating_to_chars.cc @@ -40,6 +40,10 @@ #include <string_view> #include <type_traits> +// This implementation crucially assumes float/double have the +// IEEE binary32/binary64 formats. +#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 + // Determine the binary format of 'long double'. // We support the binary64, float80 (i.e. x86 80-bit extended precision), @@ -109,8 +113,6 @@ namespace template<> struct floating_type_traits<float> { - // We (and Ryu) assume float has the IEEE binary32 format. - static_assert(__FLT_MANT_DIG__ == 24); static constexpr int mantissa_bits = 23; static constexpr int exponent_bits = 8; static constexpr bool has_implicit_leading_bit = true; @@ -124,8 +126,6 @@ namespace template<> struct floating_type_traits<double> { - // We (and Ryu) assume double has the IEEE binary64 format. - static_assert(__DBL_MANT_DIG__ == 53); static constexpr int mantissa_bits = 52; static constexpr int exponent_bits = 11; static constexpr bool has_implicit_leading_bit = true; @@ -1565,3 +1565,5 @@ _ZSt8to_charsPcS_eSt12chars_formati(char* first, char* last, double value, _GLIBCXX_END_NAMESPACE_VERSION } // namespace std + +#endif // _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 diff --git a/libstdc++-v3/testsuite/20_util/to_chars/double.cc b/libstdc++-v3/testsuite/20_util/to_chars/double.cc index 9d1f37d..bb6f744 100644 --- a/libstdc++-v3/testsuite/20_util/to_chars/double.cc +++ b/libstdc++-v3/testsuite/20_util/to_chars/double.cc @@ -32,6 +32,7 @@ // DEALINGS IN THE SOFTWARE. // { dg-do run { target c++17 } } +// { dg-require-effective-target ieee-floats } #include <charconv> diff --git a/libstdc++-v3/testsuite/20_util/to_chars/float.cc b/libstdc++-v3/testsuite/20_util/to_chars/float.cc index b890106..0c8dd4f 100644 --- a/libstdc++-v3/testsuite/20_util/to_chars/float.cc +++ b/libstdc++-v3/testsuite/20_util/to_chars/float.cc @@ -32,6 +32,7 @@ // DEALINGS IN THE SOFTWARE. // { dg-do run { target c++17 } } +// { dg-require-effective-target ieee-floats } #include <charconv> diff --git a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc index 12ac8ae..f89daa2 100644 --- a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc +++ b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc @@ -19,6 +19,7 @@ // hexadecimal floating-point literals. // { dg-do run { target c++17 } } // { dg-xfail-run-if "Ryu needs __int128" { large_long_double && { ! int128 } } } +// { dg-require-effective-target ieee-floats } #include <charconv> diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index b7d7b90..6e5634e 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -1323,6 +1323,14 @@ proc check_effective_target_futex { } { }] } +# Return 1 if float and double have the IEEE binary32 and binary64 formats. +proc check_effective_target_ieee-floats { } { + return [check_v3_target_prop_cached et_ieee_floats { + set cond "_GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64" + return [v3_check_preprocessor_condition ieee_floats $cond] + }] +} + set additional_prunes "" if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \ |