aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarinzaya <barinzaya@gmail.com>2026-01-23 15:53:29 -0500
committerBarinzaya <barinzaya@gmail.com>2026-01-23 16:19:46 -0500
commit5e4895e76dc5bb5ee4357037433825907403457e (patch)
tree2ca1f160ac89c9eadca8ca9ce3365dff6d637475 /src
parent7e39669fd1f4bc67a801d0dc5ba6eadffc7de3e5 (diff)
Fixed some issues with `in` and `not_in` on constant `bit_set`s.
This addresses two issues: - With a `bit_set` having no underlying type and a non-zero lower bound, `in` and `not_in` were returning incorrect results when done at compile-time. - With a `bit_set` of more than 128 bits, `in` always returns false on values that fall within the upper 64 bits.
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 8fdd5372b..d64c733f3 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -4125,15 +4125,19 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
i64 upper = yt->BitSet.upper;
if (lower <= key && key <= upper) {
- i64 bit = 1ll<<key;
- i64 bits = big_int_to_i64(&v.value_integer);
+ BigInt idx = big_int_make_i64(key - lower);
+ BigInt bit = big_int_make_i64(1);
+ big_int_shl_eq(&bit, &idx);
+
+ BigInt mask = {};
+ big_int_and(&mask, &bit, &v.value_integer);
x->mode = Addressing_Constant;
x->type = t_untyped_bool;
if (op.kind == Token_in) {
- x->value = exact_value_bool((bit & bits) != 0);
+ x->value = exact_value_bool(!big_int_is_zero(&mask));
} else {
- x->value = exact_value_bool((bit & bits) == 0);
+ x->value = exact_value_bool(big_int_is_zero(&mask));
}
x->expr = node;
return;