Index: llvm/include/llvm/MC/MCParser/AsmLexer.h =================================================================== --- llvm/include/llvm/MC/MCParser/AsmLexer.h +++ llvm/include/llvm/MC/MCParser/AsmLexer.h @@ -62,7 +62,7 @@ AsmToken LexDigit(); AsmToken LexSingleQuote(); AsmToken LexQuote(); - AsmToken LexFloatLiteral(); + AsmToken LexFloatLiteral(bool isDotSeperated); AsmToken LexHexFloatLiteral(bool NoIntDigits); StringRef LexUntilEndOfLine(); Index: llvm/lib/MC/MCParser/AsmLexer.cpp =================================================================== --- llvm/lib/MC/MCParser/AsmLexer.cpp +++ llvm/lib/MC/MCParser/AsmLexer.cpp @@ -61,23 +61,26 @@ return (unsigned char)*CurPtr++; } -/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)? -/// -/// The leading integral digit sequence and dot should have already been + +/// The leading integral digit sequence and dot/e should have already been /// consumed, some or all of the fractional digit sequence *can* have been /// consumed. -AsmToken AsmLexer::LexFloatLiteral() { - // Skip the fractional digit sequence. +AsmToken AsmLexer::LexFloatLiteral(bool isDotSeparated) { + // Skip the digit sequence. while (isDigit(*CurPtr)) ++CurPtr; + if (*CurPtr == '-' || *CurPtr == '+') + return ReturnError(CurPtr, "Invalid sign in float literal"); + // Check for exponent; we enforce rigidity on a correct + // literal as the upstream client cannot parse all invalid + // forms and crashes. (e.g. 1e8e8) - // 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 (isDotSeparated && (*CurPtr == 'e' || *CurPtr == 'E')){ ++CurPtr; + if (*CurPtr == '-' || *CurPtr == '+') ++CurPtr; + while (isDigit(*CurPtr)) ++CurPtr; } @@ -145,9 +148,11 @@ // Disambiguate a .1243foo identifier from a floating literal. while (isDigit(*CurPtr)) ++CurPtr; - if (*CurPtr == 'e' || *CurPtr == 'E' || - !IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) - return LexFloatLiteral(); + if (!IsIdentifierChar(*CurPtr, AllowAtInIdentifier) || + ((*CurPtr == 'e' || *CurPtr == 'E') && + (isDigit(CurPtr[1]) || + ((CurPtr[1] == '-' || CurPtr[1] == '+') && isDigit(CurPtr[2]))))) + return LexFloatLiteral(false); } while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) @@ -326,9 +331,11 @@ unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers); bool isHex = Radix == 16; // Check for floating point literals. - if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) { + if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) { ++CurPtr; - return LexFloatLiteral(); + if (CurPtr[-1] == '.') + return LexFloatLiteral(true); + return LexFloatLiteral(false); } StringRef Result(TokStart, CurPtr - TokStart); Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -198,7 +198,10 @@ 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 == '+') { Index: llvm/test/MC/AsmParser/floating-literals.s =================================================================== --- llvm/test/MC/AsmParser/floating-literals.s +++ llvm/test/MC/AsmParser/floating-literals.s @@ -48,10 +48,16 @@ .double 1.e5 # CHECK: .quad 4611686018427387904 .double 2. - -// APFloat should reject these with an error, not crash: -//.double -1.2e+ -//.double -1.2e +# 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-ERROR: Invalid sign in float literal +.double 2.+1 # CHECK: .long 1310177520 .float 0x12f7.1ep+17 Index: llvm/unittests/ADT/APFloatTest.cpp =================================================================== --- llvm/unittests/ADT/APFloatTest.cpp +++ llvm/unittests/ADT/APFloatTest.cpp @@ -1165,36 +1165,6 @@ 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");