diff options
Diffstat (limited to 'absl/strings/charconv.cc')
-rw-r--r-- | absl/strings/charconv.cc | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index 69d420bc..778a1c75 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -21,6 +21,7 @@ #include <limits> #include "absl/base/casts.h" +#include "absl/base/config.h" #include "absl/numeric/bits.h" #include "absl/numeric/int128.h" #include "absl/strings/internal/charconv_bigint.h" @@ -118,10 +119,17 @@ struct FloatTraits<double> { static constexpr int kEiselLemireMaxExclusiveExp10 = 309; static double MakeNan(const char* tagp) { +#if ABSL_HAVE_BUILTIN(__builtin_nan) + // Use __builtin_nan() if available since it has a fix for + // https://bugs.llvm.org/show_bug.cgi?id=37778 + // std::nan may use the glibc implementation. + return __builtin_nan(tagp); +#else // Support nan no matter which namespace it's in. Some platforms // incorrectly don't put it in namespace std. using namespace std; // NOLINT return nan(tagp); +#endif } // Builds a nonzero floating point number out of the provided parts. @@ -184,10 +192,17 @@ struct FloatTraits<float> { static constexpr int kEiselLemireMaxExclusiveExp10 = 39; static float MakeNan(const char* tagp) { +#if ABSL_HAVE_BUILTIN(__builtin_nanf) + // Use __builtin_nanf() if available since it has a fix for + // https://bugs.llvm.org/show_bug.cgi?id=37778 + // std::nanf may use the glibc implementation. + return __builtin_nanf(tagp); +#else // Support nanf no matter which namespace it's in. Some platforms // incorrectly don't put it in namespace std. using namespace std; // NOLINT - return nanf(tagp); + return std::nanf(tagp); +#endif } static float Make(mantissa_t mantissa, int exponent, bool sign) { @@ -203,7 +218,8 @@ struct FloatTraits<float> { if (mantissa > kMantissaMask) { // Normal value. // Adjust by 127 for the exponent representation bias, and an additional - // 23 due to the implied decimal point in the IEEE mantissa represenation. + // 23 due to the implied decimal point in the IEEE mantissa + // representation. flt += static_cast<uint32_t>(exponent + 127 + kTargetMantissaBits - 1) << 23; mantissa &= kMantissaMask; @@ -349,7 +365,8 @@ bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative, // https://bugs.llvm.org/show_bug.cgi?id=37778 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113 constexpr ptrdiff_t kNanBufferSize = 128; -#if defined(__GNUC__) || (defined(__clang__) && __clang_major__ < 7) +#if (defined(__GNUC__) && !defined(__clang__)) || \ + (defined(__clang__) && __clang_major__ < 7) volatile char n_char_sequence[kNanBufferSize]; #else char n_char_sequence[kNanBufferSize]; @@ -462,7 +479,7 @@ uint64_t ShiftRightAndRound(uint128 value, int shift, bool input_exact, // the low bit of `value` is set. // // In inexact mode, the nonzero error means the actual value is greater - // than the halfway point and we must alway round up. + // than the halfway point and we must always round up. if ((value & 1) == 1 || !input_exact) { ++value; } |