Merge pull request #6702 from Creativty/add_switch_type_duplicate_checks

Add duplicates checking in type switches
This commit is contained in:
gingerBill
2026-05-18 14:58:34 +01:00
committed by GitHub
2 changed files with 41 additions and 1 deletions

View File

@@ -9412,7 +9412,6 @@ gb_internal void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Op
multi_map_insert(seen, key, tap);
}
gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) {
if (is_type_enum(x.type)) {
// TODO(bill): Fix this logic so it's fast!!!
@@ -9441,10 +9440,50 @@ gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind u
}
}
}
gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) {
add_constant_switch_case(ctx, seen, x);
}
gb_internal void add_type_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand) {
if (operand.mode != Addressing_Type) {
return ;
}
uintptr key = type_hash_canonical_type(operand.type);
GB_ASSERT(key != 0);
isize count = multi_map_count(seen, key);
if (count) {
TEMPORARY_ALLOCATOR_GUARD();
TypeAndToken *taps = temporary_alloc_array<TypeAndToken>(count);
multi_map_get_all(seen, key, taps);
for (isize i = 0; i < count; i++) {
TypeAndToken tap = taps[i];
if (!are_types_identical(tap.type, operand.type)) {
continue;
}
TokenPos pos = tap.token.pos;
gbString expr_str = expr_to_string(operand.expr);
error(operand.expr,
"Duplicate case '%s'\n"
"\tprevious case at %s",
expr_str,
token_pos_to_string(pos));
gb_string_free(expr_str);
}
}
TypeAndToken tap = { operand.type, ast_token(operand.expr) };
multi_map_insert(seen, key, tap);
}
gb_internal void add_type_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) {
add_type_switch_case(ctx, seen, x);
}
gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) {
ast_node(bd, BasicDirective, node);

View File

@@ -1296,6 +1296,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags
}
t = default_type(t);
add_type_info_type(ctx, t);
add_type_to_seen_map(ctx, &seen, y);
} else {
convert_to_typed(ctx, &y, x.type);
if (y.mode == Addressing_Invalid) {