diff options
Diffstat (limited to 'src/check_stmt.cpp')
| -rw-r--r-- | src/check_stmt.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e81996566..d92edf41d 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1593,6 +1593,20 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ error_line("\tSuggestion: Was '#partial switch' wanted?\n"); } } + + if (build_context.strict_style) { + Token stok = ss->token; + for_array(i, bs->stmts) { + Ast *stmt = bs->stmts[i]; + if (stmt->kind != Ast_CaseClause) { + continue; + } + Token ctok = stmt->CaseClause.token; + if (ctok.pos.column > stok.pos.column) { + error(ctok, "With '-strict-style', 'case' statements must share the same column as the 'switch' token"); + } + } + } } gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { @@ -2108,10 +2122,12 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f if (init_type == nullptr) { init_type = t_invalid; } else if (is_type_polymorphic(base_type(init_type))) { + /* DISABLED: This error seems too aggressive for instantiated generic types. gbString str = type_to_string(init_type); error(vd->type, "Invalid use of a polymorphic type '%s' in variable declaration", str); gb_string_free(str); init_type = t_invalid; + */ } if (init_type == t_invalid && entity_count == 1 && (mod_flags & (Stmt_BreakAllowed|Stmt_FallthroughAllowed))) { Entity *e = entities[0]; @@ -2755,6 +2771,47 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) if (ctx->decl) { ctx->decl->defer_used += 1; } + + // NOTE(bill): Handling errors/warnings + + Ast *stmt = ds->stmt; + Ast *original_stmt = stmt; + + bool is_singular = true; + while (is_singular && stmt->kind == Ast_BlockStmt) { + Ast *inner_stmt = nullptr; + for (Ast *s : stmt->BlockStmt.stmts) { + if (s->kind == Ast_EmptyStmt) { + continue; + } + if (inner_stmt != nullptr) { + is_singular = false; + break; + } + inner_stmt = s; + } + + if (inner_stmt != nullptr) { + stmt = inner_stmt; + } + } + if (!is_singular) { + stmt = original_stmt; + } + + switch (stmt->kind) { + case_ast_node(as, AssignStmt, stmt); + if (as->op.kind != Token_Eq) { + break; + } + for (Ast *lhs : as->lhs) { + Entity *e = entity_of_node(lhs); + if (e && e->flags & EntityFlag_Result) { + error(lhs, "Assignments to named return values within 'defer' will not affect the value that is returned"); + } + } + case_end; + } } case_end; @@ -2812,6 +2869,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) case Ast_BlockStmt: case Ast_IfStmt: case Ast_SwitchStmt: + case Ast_TypeSwitchStmt: if (token.kind != Token_break) { error(bs->label, "Label '%.*s' can only be used with 'break'", LIT(e->token.string)); } |