[llvm] r357214 - [MC] Fix floating-point literal lexing.

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 28 14:12:28 PDT 2019


Author: efriedma
Date: Thu Mar 28 14:12:28 2019
New Revision: 357214

URL: http://llvm.org/viewvc/llvm-project?rev=357214&view=rev
Log:
[MC] Fix floating-point literal lexing.

This patch has three related fixes to improve float literal lexing:

1. Make AsmLexer::LexDigit handle floats without a decimal point more
   consistently.
2. Make AsmLexer::LexFloatLiteral print an error for floats which are
   apparently missing an "e".
3. Make APFloat::convertFromString use binutils-compatible exponent
   parsing.

Together, this fixes some cases where a float would be incorrectly
rejected, fixes some cases where the compiler would crash, and improves
diagnostics in some cases.

Patch by Brandon Jones.

Differential Revision: https://reviews.llvm.org/D57321


Modified:
    llvm/trunk/lib/MC/MCParser/AsmLexer.cpp
    llvm/trunk/lib/Support/APFloat.cpp
    llvm/trunk/test/MC/AsmParser/floating-literals.s
    llvm/trunk/unittests/ADT/APFloatTest.cpp

Modified: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmLexer.cpp?rev=357214&r1=357213&r2=357214&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmLexer.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmLexer.cpp Thu Mar 28 14:12:28 2019
@@ -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();
     }
 

Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=357214&r1=357213&r2=357214&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Thu Mar 28 14:12:28 2019
@@ -198,7 +198,10 @@ readExponent(StringRef::iterator begin,
   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 == '+') {

Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/floating-literals.s?rev=357214&r1=357213&r2=357214&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/floating-literals.s (original)
+++ llvm/trunk/test/MC/AsmParser/floating-literals.s Thu Mar 28 14:12:28 2019
@@ -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
+

Modified: llvm/trunk/unittests/ADT/APFloatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APFloatTest.cpp?rev=357214&r1=357213&r2=357214&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APFloatTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APFloatTest.cpp Thu Mar 28 14:12:28 2019
@@ -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, StringDecimalSignifica
   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");




More information about the llvm-commits mailing list