summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/MCParser/AsmLexer.cpp23
-rw-r--r--llvm/lib/Support/APFloat.cpp5
-rw-r--r--llvm/test/MC/AsmParser/floating-literals.s47
-rw-r--r--llvm/unittests/ADT/APFloatTest.cpp57
4 files changed, 87 insertions, 45 deletions
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp
index d21bc64c342..9155ae05d29 100644
--- a/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -61,8 +61,6 @@ int AsmLexer::getNextChar() {
return (unsigned char)*CurPtr++;
}
-/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
-///
/// The leading integral digit sequence and dot should have already been
/// consumed, some or all of the fractional digit sequence *can* have been
/// consumed.
@@ -71,13 +69,16 @@ AsmToken AsmLexer::LexFloatLiteral() {
while (isDigit(*CurPtr))
++CurPtr;
- // Check for exponent; we intentionally accept a slighlty wider set of
- // literals here and rely on the upstream client to reject invalid ones (e.g.,
- // "1e+").
- if (*CurPtr == 'e' || *CurPtr == 'E') {
+ if (*CurPtr == '-' || *CurPtr == '+')
+ return ReturnError(CurPtr, "Invalid sign in float literal");
+
+ // Check for exponent
+ if ((*CurPtr == 'e' || *CurPtr == 'E')) {
++CurPtr;
+
if (*CurPtr == '-' || *CurPtr == '+')
++CurPtr;
+
while (isDigit(*CurPtr))
++CurPtr;
}
@@ -145,8 +146,9 @@ AsmToken AsmLexer::LexIdentifier() {
// Disambiguate a .1243foo identifier from a floating literal.
while (isDigit(*CurPtr))
++CurPtr;
- if (*CurPtr == 'e' || *CurPtr == 'E' ||
- !IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
+
+ if (!IsIdentifierChar(*CurPtr, AllowAtInIdentifier) ||
+ *CurPtr == 'e' || *CurPtr == 'E')
return LexFloatLiteral();
}
@@ -326,8 +328,9 @@ AsmToken AsmLexer::LexDigit() {
unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers);
bool isHex = Radix == 16;
// Check for floating point literals.
- if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) {
- ++CurPtr;
+ if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) {
+ if (*CurPtr == '.')
+ ++CurPtr;
return LexFloatLiteral();
}
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 3ebed5b5ab8..208950d7ab7 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -198,7 +198,10 @@ readExponent(StringRef::iterator begin, StringRef::iterator end)
const unsigned int overlargeExponent = 24000; /* FIXME. */
StringRef::iterator p = begin;
- assert(p != end && "Exponent has no digits");
+ // Treat no exponent as 0 to match binutils
+ if (p == end || ((*p == '-' || *p == '+') && (p + 1) == end)) {
+ return 0;
+ }
isNegative = (*p == '-');
if (*p == '-' || *p == '+') {
diff --git a/llvm/test/MC/AsmParser/floating-literals.s b/llvm/test/MC/AsmParser/floating-literals.s
index 9dca77f8ea0..d3a2321e16f 100644
--- a/llvm/test/MC/AsmParser/floating-literals.s
+++ b/llvm/test/MC/AsmParser/floating-literals.s
@@ -27,7 +27,7 @@
# CHECK: .long 1067928519
.float 1.307
-
+
# CHECK: .quad 4617315517961601024
# CHECK: .quad 4597526701198935065
# CHECK: .quad -4600933674317040845
@@ -48,10 +48,48 @@
.double 1.e5
# CHECK: .quad 4611686018427387904
.double 2.
+# CHECK: .quad 4611686018427387904
+.double 2.e
+# CHECK: .quad 4611686018427387904
+.double 2.e+
+# CHECK: .quad 4611686018427387904
+.double 2.e-
+# CHECK: .quad -4615288898129284301
+.double -1.2e
+# CHECK: .quad 4621819117588971520
+.double 1e1
+# CHECK: .quad 4591870180066957722
+.double 1e-1
+
+
+# CHECK: .quad -4570379565595099136
+.double -1.2E3
+# CHECK: .quad -4690170861623122860
+.double -1.2E-5
+# CHECK: .quad -4465782973978902528
+.double -1.2E+10
+# CHECK: .quad 4681608360884174848
+.double 1E5
+# CHECK: .quad 4681608360884174848
+.double 1.E5
+# CHECK: .quad 4611686018427387904
+.double 2.E
+# CHECK: .quad 4611686018427387904
+.double 2.E+
+# CHECK: .quad 4611686018427387904
+.double 2.E-
+# CHECK: .quad -4615288898129284301
+.double -1.2E
+# CHECK: .quad 4621819117588971520
+.double 1E1
+# CHECK: .quad 4591870180066957722
+.double 1E-1
-// APFloat should reject these with an error, not crash:
-//.double -1.2e+
-//.double -1.2e
+
+#CHECK-ERROR: unexpected token in '.double' directive
+.double 1e1e
+# CHECK-ERROR: Invalid sign in float literal
+.double 2.+1
# CHECK: .long 1310177520
.float 0x12f7.1ep+17
@@ -83,3 +121,4 @@
# CHECK-ERROR: error: invalid hexadecimal floating-point constant: expected exponent part 'p'
.float 0x1.2
+
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index fb3607772f0..c76347ed056 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -868,6 +868,33 @@ TEST(APFloatTest, fromDecimalString) {
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(1.0, APFloat(APFloat::IEEEdouble(), "1e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1e").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1e").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1.e").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1.e").convertToDouble());
+
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), "+.1e").convertToDouble());
+ EXPECT_EQ(-0.1, APFloat(APFloat::IEEEdouble(), "-.1e").convertToDouble());
+
+ EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "1.1e").convertToDouble());
+ EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "+1.1e").convertToDouble());
+ EXPECT_EQ(-1.1, APFloat(APFloat::IEEEdouble(), "-1.1e").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e+").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e-").convertToDouble());
+
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e+").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e-").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e+").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e-").convertToDouble());
+
// These are "carefully selected" to overflow the fast log-base
// calculations in APFloat.cpp
EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
@@ -1165,36 +1192,6 @@ TEST(APFloatTest, StringDecimalSignificandDeath) {
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
}
-TEST(APFloatTest, StringDecimalExponentDeath) {
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits");
-
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
-}
-
TEST(APFloatTest, StringHexadecimalDeath) {
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
OpenPOWER on IntegriCloud