aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Gottesman <mgottesman@apple.com>2013-07-01 23:54:08 +0000
committerMichael Gottesman <mgottesman@apple.com>2013-07-01 23:54:08 +0000
commitb57770387ab262a0a23e77f094f599b6c955ba14 (patch)
tree804b42c3a0d7faeb1d682c60472d11967941bddb
parentf801b8fe7ace6306b653f5ea68c378f35e9f2d6d (diff)
downloadexternal_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.cpp9
-rw-r--r--unittests/ADT/APFloatTest.cpp25
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());