diff options
author | Eli Friedman <efriedma@quicinc.com> | 2019-03-28 21:12:28 +0000 |
---|---|---|
committer | Eli Friedman <efriedma@quicinc.com> | 2019-03-28 21:12:28 +0000 |
commit | 3dd72ea810dbb0c45c5815d2f43cc2b393d274a1 (patch) | |
tree | fd8ab38e89d21640f9637a18c98c3e62f988e397 /llvm/lib | |
parent | ea626d8bdb402b2ea91483be49e870e75c76e5e0 (diff) | |
download | bcm5719-llvm-3dd72ea810dbb0c45c5815d2f43cc2b393d274a1.tar.gz bcm5719-llvm-3dd72ea810dbb0c45c5815d2f43cc2b393d274a1.zip |
[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
llvm-svn: 357214
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmLexer.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 5 |
2 files changed, 17 insertions, 11 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 == '+') { |