mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +00:00
Make APFloat's string-parsing routines a bit safer against very large exponents.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1869ac8b71
commit
8b3f3307a2
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
|
#include <limits.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -2345,11 +2346,24 @@ APFloat::convertFromDecimalString(const StringRef &str, roundingMode rounding_mo
|
|||||||
if (decDigitValue(*D.firstSigDigit) >= 10U) {
|
if (decDigitValue(*D.firstSigDigit) >= 10U) {
|
||||||
category = fcZero;
|
category = fcZero;
|
||||||
fs = opOK;
|
fs = opOK;
|
||||||
} else if ((D.normalizedExponent + 1) * 28738
|
|
||||||
<= 8651 * (semantics->minExponent - (int) semantics->precision)) {
|
/* Check whether the normalized exponent is high enough to overflow
|
||||||
|
max during the log-rebasing in the max-exponent check below. */
|
||||||
|
} else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
|
||||||
|
fs = handleOverflow(rounding_mode);
|
||||||
|
|
||||||
|
/* If it wasn't, then it also wasn't high enough to overflow max
|
||||||
|
during the log-rebasing in the min-exponent check. Check that it
|
||||||
|
won't overflow min in either check, then perform the min-exponent
|
||||||
|
check. */
|
||||||
|
} else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
|
||||||
|
(D.normalizedExponent + 1) * 28738 <=
|
||||||
|
8651 * (semantics->minExponent - (int) semantics->precision)) {
|
||||||
/* Underflow to zero and round. */
|
/* Underflow to zero and round. */
|
||||||
zeroSignificand();
|
zeroSignificand();
|
||||||
fs = normalize(rounding_mode, lfLessThanHalf);
|
fs = normalize(rounding_mode, lfLessThanHalf);
|
||||||
|
|
||||||
|
/* We can finally safely perform the max-exponent check. */
|
||||||
} else if ((D.normalizedExponent - 1) * 42039
|
} else if ((D.normalizedExponent - 1) * 42039
|
||||||
>= 12655 * semantics->maxExponent) {
|
>= 12655 * semantics->maxExponent) {
|
||||||
/* Overflow and round. */
|
/* Overflow and round. */
|
||||||
|
@ -236,6 +236,13 @@ TEST(APFloatTest, fromDecimalString) {
|
|||||||
EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
|
EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
|
||||||
EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
|
EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
|
||||||
EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
|
EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
|
||||||
|
|
||||||
|
// These are "carefully selected" to overflow the fast log-base
|
||||||
|
// calculations in APFloat.cpp
|
||||||
|
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "99e99999").isInfinity());
|
||||||
|
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-99e99999").isInfinity());
|
||||||
|
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "1e-99999").isPosZero());
|
||||||
|
EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-1e-99999").isNegZero());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(APFloatTest, fromHexadecimalString) {
|
TEST(APFloatTest, fromHexadecimalString) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user