mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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
This commit is contained in:
parent
77962c469f
commit
d78fb504e2
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 == '+') {
|
||||
|
@ -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
|
||||
|
||||
// APFloat should reject these with an error, not crash:
|
||||
//.double -1.2e+
|
||||
//.double -1.2e
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user