mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Error on switch case fallthough if there is more than one newline #1849.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### Changes / improvements
|
||||
- Contracts @require/@ensure are no longer treated as conditionals, but must be explicitly bool.
|
||||
- Add `win-debug` setting to be able to pick dwarf for output #1855.
|
||||
- Error on switch case fallthough if there is more than one newline #1849.
|
||||
|
||||
### Fixes
|
||||
- Fix issue requiring prefix on a generic interface declaration.
|
||||
|
||||
@@ -522,9 +522,17 @@ static inline bool token_type_ends_case(TokenType type, TokenType case_type, Tok
|
||||
return type == case_type || type == default_type || type == TOKEN_RBRACE || type == TOKEN_CT_ENDSWITCH;
|
||||
}
|
||||
|
||||
static inline Ast *parse_case_stmts(ParseContext *c, TokenType case_type, TokenType default_type)
|
||||
static inline Ast *parse_case_stmts(ParseContext *c, TokenType case_type, TokenType default_type, uint32_t row)
|
||||
{
|
||||
if (token_type_ends_case(c->tok, case_type, default_type)) return NULL;
|
||||
if (token_type_ends_case(c->tok, case_type, default_type))
|
||||
{
|
||||
if (c->span.row > row + 1 && (c->tok == TOKEN_CASE || c->tok == TOKEN_DEFAULT))
|
||||
{
|
||||
PRINT_ERROR_LAST("Fallthrough cases with empty rows or comments have unclear meaning, an explicit 'break' or 'nextcase' is needed (or remove the spacing!).");
|
||||
return poisoned_ast;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
Ast *compound = new_ast(AST_COMPOUND_STMT, c->span);
|
||||
AstId *next = &compound->compound_stmt.first_stmt;
|
||||
while (!token_type_ends_case(c->tok, case_type, default_type))
|
||||
@@ -678,13 +686,14 @@ static inline Ast *parse_case_stmt(ParseContext *c, TokenType case_type, TokenTy
|
||||
{
|
||||
ASSIGN_EXPRID_OR_RET(ast->case_stmt.to_expr, parse_expr(c), poisoned_ast);
|
||||
}
|
||||
uint32_t row = c->span.row;
|
||||
if (!try_consume(c, TOKEN_COLON))
|
||||
{
|
||||
print_error_at(c->prev_span, "Missing ':' after case");
|
||||
return poisoned_ast;
|
||||
}
|
||||
RANGE_EXTEND_PREV(ast);
|
||||
ASSIGN_AST_OR_RET(ast->case_stmt.body, parse_case_stmts(c, case_type, default_type), poisoned_ast);
|
||||
ASSIGN_AST_OR_RET(ast->case_stmt.body, parse_case_stmts(c, case_type, default_type, row), poisoned_ast);
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -697,8 +706,9 @@ static inline Ast *parse_default_stmt(ParseContext *c, TokenType case_type, Toke
|
||||
Ast *ast = new_ast(AST_DEFAULT_STMT, c->span);
|
||||
advance(c);
|
||||
TRY_CONSUME_OR_RET(TOKEN_COLON, "Expected ':' after 'default'.", poisoned_ast);
|
||||
uint32_t row = c->span.row;
|
||||
RANGE_EXTEND_PREV(ast);
|
||||
ASSIGN_AST_OR_RET(ast->case_stmt.body, parse_case_stmts(c, case_type, default_type), poisoned_ast);
|
||||
ASSIGN_AST_OR_RET(ast->case_stmt.body, parse_case_stmts(c, case_type, default_type, row), poisoned_ast);
|
||||
ast->case_stmt.expr = 0;
|
||||
return ast;
|
||||
}
|
||||
|
||||
11
test/test_suite/statements/switch_error_fallthrough.c3
Normal file
11
test/test_suite/statements/switch_error_fallthrough.c3
Normal file
@@ -0,0 +1,11 @@
|
||||
fn int main()
|
||||
{
|
||||
int a;
|
||||
switch (a)
|
||||
{
|
||||
case 1: // #error: Fallthrough cases
|
||||
// ...
|
||||
case 2:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user