Skip to content

Commit 0a2e8d0

Browse files
committed
Only error after numeric suffix
Also allow digit after string postfix or numeric suffix.
1 parent 3032098 commit 0a2e8d0

File tree

3 files changed

+42
-38
lines changed

3 files changed

+42
-38
lines changed

compiler/src/dmd/lexer.d

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,10 +1973,10 @@ class Lexer
19731973
t.postfix = *p;
19741974
p++;
19751975
// disallow e.g. `@r"_"dtype var;`
1976-
if (!Ccompile && (isidchar(*p) || *p & 0x80))
1976+
if (!Ccompile && (isalpha(*p) || *p & 0x80))
19771977
{
19781978
const loc = loc();
1979-
error(loc, "alphanumeric character cannot follow string literal `%c` postfix without whitespace",
1979+
error(loc, "identifier character cannot follow string `%c` postfix without whitespace",
19801980
p[-1]);
19811981
}
19821982
break;
@@ -2000,18 +2000,6 @@ class Lexer
20002000
{
20012001
int base = 10;
20022002
const start = p;
2003-
scope (exit)
2004-
{
2005-
// disallow e.g. `@10Utype var;`
2006-
if (!Ccompile && p > start &&
2007-
(isalpha(p[-1]) || p[-1] & 0x80) &&
2008-
(isidchar(*p) || *p & 0x80))
2009-
{
2010-
const loc = loc();
2011-
error(loc, "alphanumeric character cannot follow numeric literal `%s` without whitespace",
2012-
start[0..p-start].xarraydup().ptr);
2013-
}
2014-
}
20152003
ulong n = 0; // unsigned >=64 bit integer type
20162004
int d;
20172005
bool err = false;
@@ -2205,6 +2193,7 @@ class Lexer
22052193
FLAGS flags = (base == 10) ? FLAGS.decimal : FLAGS.none;
22062194
// Parse trailing 'u', 'U', 'l' or 'L' in any combination
22072195
const psuffix = p;
2196+
LIntegerSuffix:
22082197
while (1)
22092198
{
22102199
FLAGS f;
@@ -2213,26 +2202,31 @@ class Lexer
22132202
case 'U':
22142203
case 'u':
22152204
f = FLAGS.unsigned;
2216-
goto L1;
2205+
break;
22172206
case 'l':
2218-
f = FLAGS.long_;
22192207
error("lower case integer suffix 'l' is not allowed. Please use 'L' instead");
2220-
goto L1;
2208+
goto case;
22212209
case 'L':
22222210
f = FLAGS.long_;
2223-
L1:
2224-
p++;
2225-
if ((flags & f) && !err)
2211+
break;
2212+
default:
2213+
// disallow e.g. `Foo!5Luvar;`
2214+
if (!Ccompile && flags >= FLAGS.unsigned && (isalpha(*p) || *p & 0x80))
22262215
{
2227-
error("unrecognized token");
2228-
err = true;
2216+
const loc = loc();
2217+
error(loc, "identifier character cannot follow integer `%c` suffix without whitespace",
2218+
p[-1]);
22292219
}
2230-
flags = cast(FLAGS)(flags | f);
2231-
continue;
2232-
default:
2233-
break;
2220+
break LIntegerSuffix;
22342221
}
2235-
break;
2222+
p++;
2223+
if ((flags & f) && !err)
2224+
{
2225+
error("unrecognized token");
2226+
err = true;
2227+
}
2228+
flags = cast(FLAGS)(flags | f);
2229+
continue;
22362230
}
22372231
if (base == 8 && n >= 8)
22382232
{
@@ -2609,6 +2603,7 @@ class Lexer
26092603
imaginary = true;
26102604
}
26112605

2606+
bool gotSuffix = false;
26122607
switch (*p)
26132608
{
26142609
case 'F':
@@ -2622,7 +2617,7 @@ class Lexer
26222617
if (isWellformedString && !isOutOfRange)
26232618
isOutOfRange = Port.isFloat64LiteralOutOfRange(sbufptr);
26242619
result = TOK.float64Literal;
2625-
break;
2620+
goto LcheckI;
26262621
case 'l':
26272622
if (!Ccompile)
26282623
error("use 'L' suffix instead of 'l'");
@@ -2634,13 +2629,22 @@ class Lexer
26342629
result = TOK.float80Literal;
26352630
break;
26362631
}
2637-
2632+
gotSuffix = true;
2633+
LcheckI:
26382634
if ((*p == 'i' || *p == 'I') && !Ccompile)
26392635
{
26402636
if (*p == 'I')
26412637
error("use 'i' suffix instead of 'I'");
26422638
p++;
26432639
imaginary = true;
2640+
gotSuffix = true;
2641+
}
2642+
// disallow e.g. `Foo!5fvar;`
2643+
if (!Ccompile && gotSuffix && (isalpha(*p) || *p & 0x80))
2644+
{
2645+
const loc = loc();
2646+
error(loc, "identifier character cannot follow float `%c` suffix without whitespace",
2647+
p[-1]);
26442648
}
26452649

26462650
if (imaginary)

compiler/test/fail_compilation/fail11751.d

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/*
22
TEST_OUTPUT:
33
---
4-
fail_compilation/fail11751.d(11): Error: missing exponent
5-
fail_compilation/fail11751.d(11): Error: alphanumeric character cannot follow numeric literal `0x1.FFFFFFFFFFFFFp` without whitespace
6-
fail_compilation/fail11751.d(11): Error: semicolon expected following auto declaration, not `ABC`
7-
fail_compilation/fail11751.d(11): Error: no identifier for declarator `ABC`
4+
fail_compilation/fail11751.d(10): Error: missing exponent
5+
fail_compilation/fail11751.d(10): Error: semicolon expected following auto declaration, not `ABC`
6+
fail_compilation/fail11751.d(10): Error: no identifier for declarator `ABC`
87
---
98
*/
109

compiler/test/fail_compilation/templatesingleparam.d

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
REQUIRED_ARGS: -vcolumns
33
TEST_OUTPUT:
44
---
5-
fail_compilation/templatesingleparam.d(17,14): Error: alphanumeric character cannot follow string literal `c` postfix without whitespace
6-
fail_compilation/templatesingleparam.d(18,10): Error: alphanumeric character cannot follow numeric literal `2LU` without whitespace
7-
fail_compilation/templatesingleparam.d(22,6): Error: alphanumeric character cannot follow string literal `d` postfix without whitespace
8-
fail_compilation/templatesingleparam.d(23,8): Error: alphanumeric character cannot follow numeric literal `0xFeed` without whitespace
5+
fail_compilation/templatesingleparam.d(17,14): Error: identifier character cannot follow string `c` postfix without whitespace
6+
fail_compilation/templatesingleparam.d(18,10): Error: identifier character cannot follow integer `U` suffix without whitespace
7+
fail_compilation/templatesingleparam.d(22,6): Error: identifier character cannot follow string `d` postfix without whitespace
8+
fail_compilation/templatesingleparam.d(23,4): Error: identifier character cannot follow float `f` suffix without whitespace
99
---
1010
*/
1111
class Foo(alias str) {
@@ -20,4 +20,5 @@ class Bar {
2020

2121
@`_`int i; // OK
2222
@`_`dint di;
23-
@0xFeedObject obj;
23+
@2flong fi;
24+
@0xFeedObject obj; // not caught

0 commit comments

Comments
 (0)