Skip to content

Commit a5eed38

Browse files
committed
[Lexer][SR-1724] Handle hex letters after '.' on hex number literal
The following case used to emit an error: extension Int { var asUiColor: UIColor { ... } } 0xfff.asUiColor
1 parent c62ed91 commit a5eed38

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lib/Parse/Lexer.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,11 @@ void Lexer::lexHexNumber() {
862862
if (*CurPtr != '.' && *CurPtr != 'p' && *CurPtr != 'P')
863863
return formToken(tok::integer_literal, TokStart);
864864

865+
const char *PtrOnDot = nullptr;
866+
865867
// (\.[0-9A-Fa-f][0-9A-Fa-f_]*)?
866868
if (*CurPtr == '.') {
869+
PtrOnDot = CurPtr;
867870
++CurPtr;
868871

869872
// If the character after the '.' is not a digit, assume we have an int
@@ -876,6 +879,11 @@ void Lexer::lexHexNumber() {
876879
while (isHexDigit(*CurPtr) || *CurPtr == '_')
877880
++CurPtr;
878881
if (*CurPtr != 'p' && *CurPtr != 'P') {
882+
if (!isDigit(PtrOnDot[1])) {
883+
// e.g: 0xff.description
884+
CurPtr = PtrOnDot;
885+
return formToken(tok::integer_literal, TokStart);
886+
}
879887
diagnose(CurPtr, diag::lex_expected_binary_exponent_in_hex_float_literal);
880888
return formToken(tok::unknown, TokStart);
881889
}
@@ -885,10 +893,19 @@ void Lexer::lexHexNumber() {
885893
assert(*CurPtr == 'p' || *CurPtr == 'P' && "not at a hex float exponent?!");
886894
++CurPtr;
887895

888-
if (*CurPtr == '+' || *CurPtr == '-')
896+
bool signedExponent = false;
897+
if (*CurPtr == '+' || *CurPtr == '-') {
889898
++CurPtr; // Eat the sign.
899+
signedExponent = true;
900+
}
890901

891902
if (!isDigit(*CurPtr)) {
903+
if (PtrOnDot && !isDigit(PtrOnDot[1]) && !signedExponent) {
904+
// e.g: 0xff.fpValue, 0xff.fp
905+
CurPtr = PtrOnDot;
906+
return formToken(tok::integer_literal, TokStart);
907+
}
908+
// Note: 0xff.fp+otherExpr can be valid expression. But we don't accept it.
892909
diagnose(CurPtr, diag::lex_expected_digit_in_fp_exponent);
893910
return formToken(tok::unknown, TokStart);
894911
}

test/expr/expressions.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,12 @@ func tuple_of_rvalues(_ a:Int, b:Int) -> Int {
324324
extension Int {
325325
func testLexingMethodAfterIntLiteral() {}
326326
func _0() {}
327+
// Hex letters + non hex.
328+
func describe() {}
329+
// Hex letters + 'p'.
330+
func eap() {}
331+
// Hex letters + 'p' + non hex.
332+
func fpValue() {}
327333
}
328334

329335
123.testLexingMethodAfterIntLiteral()
@@ -336,6 +342,10 @@ extension Int {
336342
0o123._0()
337343
0x1FFF._0()
338344

345+
0x1FFF.describe()
346+
0x1FFF.eap()
347+
0x1FFF.fpValue()
348+
339349
var separator1: Int = 1_
340350
var separator2: Int = 1_000
341351
var separator4: Int = 0b1111_0000_

0 commit comments

Comments
 (0)