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>

Reply via email to