summaryrefslogtreecommitdiff
path: root/absl/strings/charconv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/charconv.cc')
-rw-r--r--absl/strings/charconv.cc25
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;
}