diff --git a/compiler/src/dmd/lexer.d b/compiler/src/dmd/lexer.d index db29ff263c00..760656fe3ca3 100644 --- a/compiler/src/dmd/lexer.d +++ b/compiler/src/dmd/lexer.d @@ -1973,10 +1973,10 @@ class Lexer t.postfix = *p; p++; // disallow e.g. `@r"_"dtype var;` - if (!Ccompile && (isidchar(*p) || *p & 0x80)) + if (!Ccompile && (isalpha(*p) || *p & 0x80)) { const loc = loc(); - error(loc, "alphanumeric character cannot follow string literal `%c` postfix without whitespace", + error(loc, "identifier character cannot follow string `%c` postfix without whitespace", p[-1]); } break; @@ -2000,18 +2000,6 @@ class Lexer { int base = 10; const start = p; - scope (exit) - { - // disallow e.g. `@10Utype var;` - if (!Ccompile && p > start && - (isalpha(p[-1]) || p[-1] & 0x80) && - (isidchar(*p) || *p & 0x80)) - { - const loc = loc(); - error(loc, "alphanumeric character cannot follow numeric literal `%s` without whitespace", - start[0..p-start].xarraydup().ptr); - } - } ulong n = 0; // unsigned >=64 bit integer type int d; bool err = false; @@ -2205,6 +2193,7 @@ class Lexer FLAGS flags = (base == 10) ? FLAGS.decimal : FLAGS.none; // Parse trailing 'u', 'U', 'l' or 'L' in any combination const psuffix = p; +LIntegerSuffix: while (1) { FLAGS f; @@ -2213,26 +2202,31 @@ class Lexer case 'U': case 'u': f = FLAGS.unsigned; - goto L1; + break; case 'l': - f = FLAGS.long_; error("lower case integer suffix 'l' is not allowed. Please use 'L' instead"); - goto L1; + goto case; case 'L': f = FLAGS.long_; - L1: - p++; - if ((flags & f) && !err) + break; + default: + // disallow e.g. `Foo!5Luvar;` + if (!Ccompile && flags >= FLAGS.unsigned && (isalpha(*p) || *p & 0x80)) { - error("repeated integer suffix `%c`", p[-1]); - err = true; + const loc = loc(); + error(loc, "identifier character cannot follow integer `%c` suffix without whitespace", + p[-1]); } - flags = cast(FLAGS)(flags | f); - continue; - default: - break; + break LIntegerSuffix; } - break; + p++; + if ((flags & f) && !err) + { + error("repeated integer suffix `%c`", p[-1]); + err = true; + } + flags = cast(FLAGS)(flags | f); + continue; } if (base == 8 && n >= 8) { @@ -2609,6 +2603,7 @@ class Lexer imaginary = true; } + bool gotSuffix = false; switch (*p) { case 'F': @@ -2622,7 +2617,7 @@ class Lexer if (isWellformedString && !isOutOfRange) isOutOfRange = Port.isFloat64LiteralOutOfRange(sbufptr); result = TOK.float64Literal; - break; + goto LcheckI; case 'l': if (!Ccompile) error("use 'L' suffix instead of 'l'"); @@ -2634,13 +2629,22 @@ class Lexer result = TOK.float80Literal; break; } - + gotSuffix = true; +LcheckI: if ((*p == 'i' || *p == 'I') && !Ccompile) { if (*p == 'I') error("use 'i' suffix instead of 'I'"); p++; imaginary = true; + gotSuffix = true; + } + // disallow e.g. `Foo!5fvar;` + if (!Ccompile && gotSuffix && (isalpha(*p) || *p & 0x80)) + { + const loc = loc(); + error(loc, "identifier character cannot follow float `%c` suffix without whitespace", + p[-1]); } if (imaginary) diff --git a/compiler/test/fail_compilation/fail11751.d b/compiler/test/fail_compilation/fail11751.d index b1fd248a75b2..36d7f9d8e302 100644 --- a/compiler/test/fail_compilation/fail11751.d +++ b/compiler/test/fail_compilation/fail11751.d @@ -1,10 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/fail11751.d(11): Error: missing exponent -fail_compilation/fail11751.d(11): Error: alphanumeric character cannot follow numeric literal `0x1.FFFFFFFFFFFFFp` without whitespace -fail_compilation/fail11751.d(11): Error: semicolon expected following auto declaration, not `ABC` -fail_compilation/fail11751.d(11): Error: no identifier for declarator `ABC` +fail_compilation/fail11751.d(10): Error: missing exponent +fail_compilation/fail11751.d(10): Error: semicolon expected following auto declaration, not `ABC` +fail_compilation/fail11751.d(10): Error: no identifier for declarator `ABC` --- */ diff --git a/compiler/test/fail_compilation/templatesingleparam.d b/compiler/test/fail_compilation/templatesingleparam.d index f6b524031b0d..7e5a9368585b 100644 --- a/compiler/test/fail_compilation/templatesingleparam.d +++ b/compiler/test/fail_compilation/templatesingleparam.d @@ -2,10 +2,10 @@ REQUIRED_ARGS: -vcolumns TEST_OUTPUT: --- -fail_compilation/templatesingleparam.d(17,14): Error: alphanumeric character cannot follow string literal `c` postfix without whitespace -fail_compilation/templatesingleparam.d(18,10): Error: alphanumeric character cannot follow numeric literal `2LU` without whitespace -fail_compilation/templatesingleparam.d(22,6): Error: alphanumeric character cannot follow string literal `d` postfix without whitespace -fail_compilation/templatesingleparam.d(23,8): Error: alphanumeric character cannot follow numeric literal `0xFeed` without whitespace +fail_compilation/templatesingleparam.d(17,14): Error: identifier character cannot follow string `c` postfix without whitespace +fail_compilation/templatesingleparam.d(18,10): Error: identifier character cannot follow integer `U` suffix without whitespace +fail_compilation/templatesingleparam.d(22,6): Error: identifier character cannot follow string `d` postfix without whitespace +fail_compilation/templatesingleparam.d(23,4): Error: identifier character cannot follow float `f` suffix without whitespace --- */ class Foo(alias str) { @@ -20,4 +20,5 @@ class Bar { @`_`int i; // OK @`_`dint di; -@0xFeedObject obj; +@2flong fi; +@0xFeedObject obj; // not caught