When we're using fast_float for 32- and 64-bit floating point, use strtold for wider long double, even if locales are unavailable.
On vxworks, test for strtof's and strtold's declarations, so that they can be used even when cross compiling. Include stdlib.h in the decl-checking macro, so that it can find them. Regstrapped on x86_64-linux-gnu. Also tested on aarch64-vx7r2 with gcc-12, where uselocale is not available, and using strtold rather than fast_math's double fallback avoids a couple of from_chars-related testsuite fails (from_chars/4.cc and to_chars/long_double.cc). Ok to install? for libstdc++-v3/ChangeLog * src/c++17/floating_from_chars.cc (USE_STRTOD_FOR_FROM_CHARS): Define when using fast_float if long double is not as wide as double and strtold is not broken. * crossconfig.m4: Test for strtof and strtold declarations on vxworks. (GLIBCXX_CHECK_MATH_DECL): Include stdlib.h too. * configure: Rebuilt. --- libstdc++-v3/configure | 131 +++++++++++++++++++++++++ libstdc++-v3/crossconfig.m4 | 3 - libstdc++-v3/src/c++17/floating_from_chars.cc | 10 ++ 3 files changed, 143 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure [omitted] diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 index b3269cb88e077..9db32f4d422da 100644 --- a/libstdc++-v3/crossconfig.m4 +++ b/libstdc++-v3/crossconfig.m4 @@ -293,7 +293,7 @@ dnl # switch to more elaborate tests. GLIBCXX_CHECK_MATH_DECLS([ acosl asinl atan2l atanl ceill cosl coshl expl fabsl floorl fmodl frexpl ldexpl log10l logl modfl powl sinl sinhl sqrtl tanl tanhl hypotl - ldexpf modff hypotf frexpf]) + ldexpf modff hypotf frexpf strtof strtold]) dnl # sincosl is the only one missing here, compared with the *l dnl # functions in the list guarded by dnl # long_double_math_on_this_cpu in configure.ac, right after @@ -323,6 +323,7 @@ AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ AC_LANG_SAVE AC_LANG_C AC_TRY_COMPILE([ +#include <stdlib.h> #include <math.h> #ifdef HAVE_IEEEFP_H # include <ieeefp.h> diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc index 78b9d92cdc0fa..15af811d198c4 100644 --- a/libstdc++-v3/src/c++17/floating_from_chars.cc +++ b/libstdc++-v3/src/c++17/floating_from_chars.cc @@ -80,6 +80,10 @@ extern "C" _Float128 __strtof128(const char*, char**) # if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__ // No need to use strtold. # undef USE_STRTOD_FOR_FROM_CHARS +# elif !defined USE_STRTOD_FOR_FROM_CHARS \ + && defined _GLIBCXX_HAVE_STRTOLD && !defined _GLIBCXX_HAVE_BROKEN_STRTOLD +// A working strtold will be more compliant than fast_float's double. +# define USE_STRTOD_FOR_FROM_CHARS 1 # endif #endif @@ -607,9 +611,11 @@ namespace ptrdiff_t from_chars_impl(const char* str, T& value, errc& ec) noexcept { +#if _GLIBCXX_HAVE_USELOCALE if (locale_t loc = ::newlocale(LC_ALL_MASK, "C", (locale_t)0)) [[likely]] { locale_t orig = ::uselocale(loc); +#endif #if _GLIBCXX_USE_C99_FENV_TR1 && defined(FE_TONEAREST) const int rounding = std::fegetround(); @@ -652,8 +658,10 @@ namespace std::fesetround(rounding); #endif +#if _GLIBCXX_HAVE_USELOCALE ::uselocale(orig); ::freelocale(loc); +#endif const ptrdiff_t n = endptr - str; if (conv_errno == ERANGE) [[unlikely]] @@ -674,9 +682,11 @@ namespace ec = errc(); } return n; +#if _GLIBCXX_HAVE_USELOCALE } else if (errno == ENOMEM) ec = errc::not_enough_memory; +#endif return 0; } -- Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer Disinformation flourishes because many people care deeply about injustice but very few check the facts. Ask me about <https://stallmansupport.org>