diff options
| author | Michael Gottesman <mgottesman@apple.com> | 2013-07-01 23:54:08 +0000 |
|---|---|---|
| committer | Michael Gottesman <mgottesman@apple.com> | 2013-07-01 23:54:08 +0000 |
| commit | b57770387ab262a0a23e77f094f599b6c955ba14 (patch) | |
| tree | 804b42c3a0d7faeb1d682c60472d11967941bddb | |
| parent | f801b8fe7ace6306b653f5ea68c378f35e9f2d6d (diff) | |
| download | external_llvm-b57770387ab262a0a23e77f094f599b6c955ba14.zip external_llvm-b57770387ab262a0a23e77f094f599b6c955ba14.tar.gz external_llvm-b57770387ab262a0a23e77f094f599b6c955ba14.tar.bz2 | |
[APFloat] Ensure that we can properly parse strings that do not have null terminators.
rdar://14323230
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185397 91177308-0d34-0410-b5e6-96231b3b80d8
| -rw-r--r-- | lib/Support/APFloat.cpp | 9 | ||||
| -rw-r--r-- | unittests/ADT/APFloatTest.cpp | 25 |
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index a7ff9f6..ae4a101 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -2481,7 +2481,14 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] */ - if (decDigitValue(*D.firstSigDigit) >= 10U) { + // Test if we have a zero number allowing for strings with no null terminators + // and zero decimals with non-zero exponents. + // + // We computed firstSigDigit by ignoring all zeros and dots. Thus if + // D->firstSigDigit equals str.end(), every digit must be a zero and there can + // be at most one dot. On the other hand, if we have a zero with a non-zero + // exponent, then we know that D.firstSigDigit will be non-numeric. + if (decDigitValue(*D.firstSigDigit) >= 10U || D.firstSigDigit == str.end()) { category = fcZero; fs = opOK; diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index d322bcd..46dfbd1 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -538,6 +538,31 @@ TEST(APFloatTest, Zero) { EXPECT_TRUE(APFloat(-0.0).isNegative()); } +TEST(APFloatTest, DecimalStringsWithoutNullTerminators) { + // Make sure that we can parse strings without null terminators. + // rdar://14323230. + APFloat Val(APFloat::IEEEdouble); + Val.convertFromString(StringRef("0.00", 3), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.0); + Val.convertFromString(StringRef("0.01", 3), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.0); + Val.convertFromString(StringRef("0.09", 3), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.0); + Val.convertFromString(StringRef("0.095", 4), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.09); + Val.convertFromString(StringRef("0.00e+3", 7), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.00); + Val.convertFromString(StringRef("0e+3", 4), + llvm::APFloat::rmNearestTiesToEven); + EXPECT_EQ(Val.convertToDouble(), 0.00); + +} + TEST(APFloatTest, fromZeroDecimalString) { EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0").convertToDouble()); EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0").convertToDouble()); |
