extend () error msgs for if conditions to other statement conditions (#14353)

This commit is contained in:
Walter Bright 2022-08-07 22:23:44 -07:00 committed by GitHub
parent 50d37f238c
commit 2265d6cb35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 28 deletions

View file

@ -5331,6 +5331,33 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
error(loc, "instead of C-style syntax, use D-style `%s%s%s`", t.toChars(), sp, s);
}
/*****************************
* Ad-hoc error message for missing or extra parens that close a condition.
* Params:
* start = "if", "while", etc. Must be 0 terminated.
* param = if the condition is a declaration, this will be non-null
* condition = if param is null, then this is the conditional Expression. If condition is null,
* then an error in the condition was already reported.
*/
private void closeCondition(string start, AST.Parameter param, AST.Expression condition)
{
string format;
if (token.value != TOK.rightParenthesis && condition)
{
format = "missing closing `)` after `%s (%s`";
}
else
check(TOK.rightParenthesis);
if (token.value == TOK.rightParenthesis)
{
if (condition) // if not an error in condition
format = "extra `)` after `%s (%s)`";
nextToken();
}
if (format)
error(format.ptr, start.ptr, param ? "declaration".ptr : condition.toChars());
}
/*****************************************
* Parses `foreach` statements, `static foreach` statements and
* `static foreach` declarations.
@ -5961,12 +5988,12 @@ LagainStc:
}
case TOK.while_:
{
AST.Parameter param = null;
nextToken();
check(TOK.leftParenthesis);
param = parseAssignCondition();
AST.Expression condition = parseExpression();
check(TOK.rightParenthesis);
auto param = parseAssignCondition();
auto condition = parseExpression();
closeCondition("while", param, condition);
Loc endloc;
AST.Statement _body = parseStatement(ParseStatementFlags.scope_, null, &endloc);
s = new AST.WhileStatement(loc, condition, _body, endloc, param);
@ -5987,7 +6014,6 @@ LagainStc:
case TOK.do_:
{
AST.Statement _body;
AST.Expression condition;
nextToken();
const lookingForElseSave = lookingForElse;
@ -5996,8 +6022,8 @@ LagainStc:
lookingForElse = lookingForElseSave;
check(TOK.while_);
check(TOK.leftParenthesis);
condition = parseExpression();
check(TOK.rightParenthesis);
auto condition = parseExpression();
closeCondition("do .. while", null, condition);
if (token.value == TOK.semicolon)
nextToken();
else
@ -6058,25 +6084,11 @@ LagainStc:
}
case TOK.if_:
{
AST.Parameter param = null;
AST.Expression condition;
nextToken();
check(TOK.leftParenthesis);
param = parseAssignCondition();
condition = parseExpression();
if (token.value != TOK.rightParenthesis && condition)
{
error("missing closing `)` after `if (%s`", param ? "declaration".ptr : condition.toChars());
}
else
check(TOK.rightParenthesis);
if (token.value == TOK.rightParenthesis)
{
if (condition) // if not an error in condition
error("extra `)` after `if (%s)`", param ? "declaration".ptr : condition.toChars());
nextToken();
}
auto param = parseAssignCondition();
auto condition = parseExpression();
closeCondition("if", param, condition);
{
const lookingForElseSave = lookingForElse;
@ -6223,7 +6235,7 @@ LagainStc:
nextToken();
check(TOK.leftParenthesis);
AST.Expression condition = parseExpression();
check(TOK.rightParenthesis);
closeCondition("switch", null, condition);
AST.Statement _body = parseStatement(ParseStatementFlags.scope_);
s = new AST.SwitchStatement(loc, condition, _body, isfinal);
break;
@ -6402,7 +6414,7 @@ LagainStc:
{
nextToken();
exp = parseExpression();
check(TOK.rightParenthesis);
closeCondition("synchronized", null, exp);
}
else
exp = null;
@ -6419,7 +6431,7 @@ LagainStc:
nextToken();
check(TOK.leftParenthesis);
exp = parseExpression();
check(TOK.rightParenthesis);
closeCondition("with", null, exp);
_body = parseStatement(ParseStatementFlags.scope_, null, &endloc);
s = new AST.WithStatement(loc, exp, _body, endloc);
break;

View file

@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` when expecting `(`
fail_compilation/ice8795.d-mixin-14(14): Error: expression expected, not `End of File`
fail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` when expecting `)`
fail_compilation/ice8795.d-mixin-14(14): Error: missing closing `)` after `switch (0`
fail_compilation/ice8795.d-mixin-14(14): Error: found `End of File` instead of statement
fail_compilation/ice8795.d-mixin-15(15): Error: { } expected following `interface` declaration
fail_compilation/ice8795.d-mixin-15(15): Error: anonymous interfaces not allowed