libstdc++: Check _GLIBCXX_USE_C99_STDLIB for strtof and strtold
authorJonathan Wakely <jwakely@redhat.com>
Thu, 30 Jul 2020 19:55:56 +0000 (20:55 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 30 Jul 2020 19:55:56 +0000 (20:55 +0100)
On broken systems we only have strtod, not strtof and strtold. Just use
strtod for all types, even though that will produce incorrect results in
some cases.

Similarly, if _GLIBCXX_USE_C99_MATH is not defined then std::isinf won't
be declared. Just refer to it unqualified, which should find the C
library's isinf macro if that hasn't been #undef'd by <cmath>.

libstdc++-v3/ChangeLog:

* src/c++17/floating_from_chars.cc (from_chars_impl): Use
isinf unqualified.
[!_GLIBCXX_USE_C99_STDLIB]: Use strtod for float and long
double.

libstdc++-v3/src/c++17/floating_from_chars.cc

index f1519e5c7b6abc4390b541fd14a746d3e6078a45..26b69a3852150f6f2b07116e48a392fe1c6d5120 100644 (file)
@@ -300,12 +300,16 @@ namespace
        errno = 0;
        char* endptr;
        T tmpval;
+#if _GLIBCXX_USE_C99_STDLIB
        if constexpr (is_same_v<T, float>)
          tmpval = std::strtof(str, &endptr);
-       if constexpr (is_same_v<T, double>)
+       else if constexpr (is_same_v<T, double>)
          tmpval = std::strtod(str, &endptr);
        else if constexpr (is_same_v<T, long double>)
          tmpval = std::strtold(str, &endptr);
+#else
+       tmpval = std::strtod(str, &endptr);
+#endif
        const int conv_errno = std::__exchange(errno, save_errno);
 
 #if _GLIBCXX_USE_C99_FENV_TR1
@@ -319,7 +323,7 @@ namespace
        const ptrdiff_t n = endptr - str;
        if (conv_errno == ERANGE) [[unlikely]]
          {
-           if (std::isinf(tmpval)) // overflow
+           if (isinf(tmpval)) // overflow
              ec = errc::result_out_of_range;
            else // underflow (LWG 3081 wants to set value = tmpval here)
              ec = errc::result_out_of_range;