diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-29 01:00:09 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-29 01:00:10 +0200 |
commit | 0e1866017fd389629629b150ce252820592506cd (patch) | |
tree | 681142ae0e610ef7af2a43ca2d62c3ea5ed5f91a /src/3rdparty/double-conversion/strtod.cc | |
parent | 9567a34bc0d9be87d3b0d6cbcb841837ca1d5659 (diff) | |
parent | 9a8175a13124e156948914854d2fda7436065b08 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I6083c3e61b7dbe188f83676f7e7bb268e5ccf2f3
Diffstat (limited to 'src/3rdparty/double-conversion/strtod.cc')
-rw-r--r-- | src/3rdparty/double-conversion/strtod.cc | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc index 17abcbb2a5..e8cc13f2de 100644 --- a/src/3rdparty/double-conversion/strtod.cc +++ b/src/3rdparty/double-conversion/strtod.cc @@ -25,13 +25,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include <stdarg.h> -#include <limits.h> +#include <climits> +#include <cstdarg> -#include "strtod.h" -#include "bignum.h" -#include "cached-powers.h" -#include "ieee.h" +#include <double-conversion/bignum.h> +#include <double-conversion/cached-powers.h> +#include <double-conversion/ieee.h> +#include <double-conversion/strtod.h> namespace double_conversion { @@ -205,7 +205,7 @@ static bool DoubleStrtod(Vector<const char> trimmed, // Note that the ARM simulator is compiled for 32bits. It therefore exhibits // the same problem. return false; -#endif +#else if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { int read_digits; // The trimmed input fits into a double. @@ -243,6 +243,7 @@ static bool DoubleStrtod(Vector<const char> trimmed, } } return false; +#endif } @@ -471,6 +472,30 @@ double Strtod(Vector<const char> buffer, int exponent) { } } +static float SanitizedDoubletof(double d) { + ASSERT(d >= 0.0); + // ASAN has a sanitize check that disallows casting doubles to floats if + // they are too big. + // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks + // The behavior should be covered by IEEE 754, but some projects use this + // flag, so work around it. + float max_finite = 3.4028234663852885981170418348451692544e+38; + // The half-way point between the max-finite and infinity value. + // Since infinity has an even significand everything equal or greater than + // this value should become infinity. + double half_max_finite_infinity = + 3.40282356779733661637539395458142568448e+38; + if (d >= max_finite) { + if (d >= half_max_finite_infinity) { + return Single::Infinity(); + } else { + return max_finite; + } + } else { + return static_cast<float>(d); + } +} + float Strtof(Vector<const char> buffer, int exponent) { char copy_buffer[kMaxSignificantDecimalDigits]; Vector<const char> trimmed; @@ -482,7 +507,7 @@ float Strtof(Vector<const char> buffer, int exponent) { double double_guess; bool is_correct = ComputeGuess(trimmed, exponent, &double_guess); - float float_guess = static_cast<float>(double_guess); + float float_guess = SanitizedDoubletof(double_guess); if (float_guess == double_guess) { // This shortcut triggers for integer values. return float_guess; @@ -505,15 +530,15 @@ float Strtof(Vector<const char> buffer, int exponent) { double double_next = Double(double_guess).NextDouble(); double double_previous = Double(double_guess).PreviousDouble(); - float f1 = static_cast<float>(double_previous); + float f1 = SanitizedDoubletof(double_previous); float f2 = float_guess; - float f3 = static_cast<float>(double_next); + float f3 = SanitizedDoubletof(double_next); float f4; if (is_correct) { f4 = f3; } else { double double_next2 = Double(double_next).NextDouble(); - f4 = static_cast<float>(double_next2); + f4 = SanitizedDoubletof(double_next2); } (void) f2; // Mark variable as used. ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4); @@ -528,7 +553,7 @@ float Strtof(Vector<const char> buffer, int exponent) { (f1 == f2 && f2 != f3 && f3 == f4) || (f1 == f2 && f2 == f3 && f3 != f4)); - // guess and next are the two possible canditates (in the same way that + // guess and next are the two possible candidates (in the same way that // double_guess was the lower candidate for a double-precision guess). float guess = f1; float next = f4; |