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.
This commit is contained in:
parent
e798f08192
commit
6a31d47e27
@ -688,6 +688,20 @@ namespace std
|
|||||||
# endif
|
# endif
|
||||||
#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 __has_builtin
|
||||||
# ifdef __is_identifier
|
# ifdef __is_identifier
|
||||||
// Intel and older Clang require !__is_identifier for some built-ins:
|
// Intel and older Clang require !__is_identifier for some built-ins:
|
||||||
|
@ -702,6 +702,7 @@ namespace __detail
|
|||||||
chars_format __fmt = chars_format::general) noexcept;
|
chars_format __fmt = chars_format::general) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
|
||||||
// Floating-point std::to_chars
|
// Floating-point std::to_chars
|
||||||
|
|
||||||
// Overloads for float.
|
// Overloads for float.
|
||||||
@ -725,6 +726,7 @@ namespace __detail
|
|||||||
chars_format __fmt) noexcept;
|
chars_format __fmt) noexcept;
|
||||||
to_chars_result to_chars(char* __first, char* __last, long double __value,
|
to_chars_result to_chars(char* __first, char* __last, long double __value,
|
||||||
chars_format __fmt, int __precision) noexcept;
|
chars_format __fmt, int __precision) noexcept;
|
||||||
|
#endif
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
@ -40,6 +40,10 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#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'.
|
// Determine the binary format of 'long double'.
|
||||||
|
|
||||||
// We support the binary64, float80 (i.e. x86 80-bit extended precision),
|
// We support the binary64, float80 (i.e. x86 80-bit extended precision),
|
||||||
@ -109,8 +113,6 @@ namespace
|
|||||||
template<>
|
template<>
|
||||||
struct floating_type_traits<float>
|
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 mantissa_bits = 23;
|
||||||
static constexpr int exponent_bits = 8;
|
static constexpr int exponent_bits = 8;
|
||||||
static constexpr bool has_implicit_leading_bit = true;
|
static constexpr bool has_implicit_leading_bit = true;
|
||||||
@ -124,8 +126,6 @@ namespace
|
|||||||
template<>
|
template<>
|
||||||
struct floating_type_traits<double>
|
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 mantissa_bits = 52;
|
||||||
static constexpr int exponent_bits = 11;
|
static constexpr int exponent_bits = 11;
|
||||||
static constexpr bool has_implicit_leading_bit = true;
|
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
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// { dg-do run { target c++17 } }
|
// { dg-do run { target c++17 } }
|
||||||
|
// { dg-require-effective-target ieee-floats }
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// { dg-do run { target c++17 } }
|
// { dg-do run { target c++17 } }
|
||||||
|
// { dg-require-effective-target ieee-floats }
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
// hexadecimal floating-point literals.
|
// hexadecimal floating-point literals.
|
||||||
// { dg-do run { target c++17 } }
|
// { dg-do run { target c++17 } }
|
||||||
// { dg-xfail-run-if "Ryu needs __int128" { large_long_double && { ! int128 } } }
|
// { dg-xfail-run-if "Ryu needs __int128" { large_long_double && { ! int128 } } }
|
||||||
|
// { dg-require-effective-target ieee-floats }
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
|
||||||
|
@ -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 ""
|
set additional_prunes ""
|
||||||
|
|
||||||
if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
|
if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user