-
-
Notifications
You must be signed in to change notification settings - Fork 608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Issue 23999 - literal suffixes dont mix well with template instan… #15339
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1964,7 +1964,7 @@ class Lexer | |
/*************************************** | ||
* Get postfix of string literal. | ||
*/ | ||
private void stringPostfix(Token* t) pure @nogc | ||
private void stringPostfix(Token* t) | ||
{ | ||
switch (*p) | ||
{ | ||
|
@@ -1973,6 +1973,13 @@ class Lexer | |
case 'd': | ||
t.postfix = *p; | ||
p++; | ||
// disallow e.g. `@r"_"dtype var;` | ||
if (!Ccompile && isalpha(*p)) | ||
{ | ||
const loc = loc(); | ||
error(loc, "identifier character cannot follow string `%c` postfix without whitespace", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say "invalid suffix character %c", because other syntax is not an issue. |
||
p[-1]); | ||
} | ||
break; | ||
default: | ||
t.postfix = 0; | ||
|
@@ -2187,6 +2194,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; | ||
|
@@ -2195,26 +2203,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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need Ccompile check or flags check |
||
{ | ||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this loop seems more complicated than necessary |
||
} | ||
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) | ||
{ | ||
|
@@ -2591,6 +2604,7 @@ class Lexer | |
imaginary = true; | ||
} | ||
|
||
bool gotSuffix = false; | ||
switch (*p) | ||
{ | ||
case 'F': | ||
|
@@ -2604,7 +2618,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'"); | ||
|
@@ -2616,13 +2630,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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't think it would be a problem if Ccompile was true There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't think gotSuffix is needed, just check for invalid suffix alpha |
||
{ | ||
const loc = loc(); | ||
error(loc, "identifier character cannot follow float `%c` suffix without whitespace", | ||
p[-1]); | ||
} | ||
|
||
if (imaginary) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
REQUIRED_ARGS: -vcolumns | ||
TEST_OUTPUT: | ||
--- | ||
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) { | ||
enum STR = str; | ||
} | ||
|
||
class Bar { | ||
Foo!q{foo}bb; // OK | ||
Foo!q{foo}cc; | ||
Foo!2LUNGS; | ||
} | ||
|
||
@`_`int i; // OK | ||
@`_`dint di; | ||
@2flong fi; | ||
@0xFeedObject obj; // not caught |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's already in not Ccompile land.