aboutsummaryrefslogtreecommitdiff
path: root/src/check_stmt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-05-13 00:57:10 +0100
committergingerBill <bill@gingerbill.org>2021-05-13 00:57:10 +0100
commitbe12f12c3c2872fd89021af16c2ab838277c4c4a (patch)
treec383925cf5bdd8a16e5836ab12fe2fb8dcc10e06 /src/check_stmt.cpp
parent2e5f57d8a18352c02da72f2f2385116a099d7942 (diff)
Fix #814
Diffstat (limited to 'src/check_stmt.cpp')
-rw-r--r--src/check_stmt.cpp41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index a3c9a529c..9ca53c4fc 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -960,9 +960,44 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
Operand b1 = rhs;
check_comparison(ctx, &a1, &b1, Token_LtEq);
- add_constant_switch_case(ctx, &seen, lhs);
- if (upper_op == Token_GtEq) {
- add_constant_switch_case(ctx, &seen, rhs);
+ if (is_type_enum(x.type)) {
+ // TODO(bill): Fix this logic so it's fast!!!
+
+ i64 v0 = exact_value_to_i64(lhs.value);
+ i64 v1 = exact_value_to_i64(rhs.value);
+ Operand v = {};
+ v.mode = Addressing_Constant;
+ v.type = x.type;
+ v.expr = x.expr;
+
+ Type *bt = base_type(x.type);
+ GB_ASSERT(bt->kind == Type_Enum);
+ for (i64 vi = v0; vi <= v1; vi++) {
+ if (upper_op != Token_GtEq && vi == v1) {
+ break;
+ }
+
+ bool found = false;
+ for_array(j, bt->Enum.fields) {
+ Entity *f = bt->Enum.fields[j];
+ GB_ASSERT(f->kind == Entity_Constant);
+
+ i64 fv = exact_value_to_i64(f->Constant.value);
+ if (fv == vi) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ v.value = exact_value_i64(vi);
+ add_constant_switch_case(ctx, &seen, v);
+ }
+ }
+ } else {
+ add_constant_switch_case(ctx, &seen, lhs);
+ if (upper_op == Token_GtEq) {
+ add_constant_switch_case(ctx, &seen, rhs);
+ }
}
if (is_type_string(x.type)) {