diff --git a/releasenotes.md b/releasenotes.md index 32218ec19..105816245 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -6,6 +6,7 @@ ### Fixes - Bug in `io::write_using_write_byte`. +- Bitstruct value cannot be used to index a const array in compile time. #2512 ### Stdlib changes diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 6cad425b3..75c6c5f38 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3855,7 +3855,7 @@ static inline bool sema_expr_resolve_subscript_index(SemaContext *context, Expr } else { - if (!sema_analyse_expr(context, index)) + if (!sema_analyse_expr_rvalue(context, index)) { expr_poison(index); return false; @@ -3875,7 +3875,7 @@ static inline bool sema_expr_resolve_subscript_index(SemaContext *context, Expr ArrayIndex size; bool check_len = !context->call_env.in_no_eval || current_type == type_untypedlist; Expr *len_expr = current_expr->expr_kind == EXPR_CT_IDENT ? current_expr->ct_ident_expr.decl->var.init_expr : current_expr; - if (expr_is_const_int(index) && (size = sema_len_from_expr(len_expr)) >= 0) + if (sema_cast_const(index)&& expr_is_const_int(index) && (size = sema_len_from_expr(len_expr)) >= 0) { // 4c. And that it's in range. if (int_is_neg(index->const_expr.ixx)) diff --git a/test/test_suite/bitstruct/bitstruct_to_index.c3t b/test/test_suite/bitstruct/bitstruct_to_index.c3t new file mode 100644 index 000000000..844993520 --- /dev/null +++ b/test/test_suite/bitstruct/bitstruct_to_index.c3t @@ -0,0 +1,25 @@ +// #target: macos-x64 +module test; +import std; + +bitstruct Some : char +{ + char v : 0 .. 4; +} + +const int[8] SOME_MAP = some_macro(); + +macro some_macro() +{ + Some $s = { 8 }; + int[8] $map; + $for var $i = 0; $i < 4; $i++: + $s = { .v = $s.v >> 1 }; + $map[$s.v] = 1; + $endfor; + return $map; +} + +/* #expect: test.ll + +@test.SOME_MAP = local_unnamed_addr constant { i32, i32, i32, i32, i32, [3 x i32] } { i32 1, i32 1, i32 1, i32 0, i32 1, [3 x i32] zeroinitializer }, align 16