diff --git a/releasenotes.md b/releasenotes.md index d47a0fcfb..385315ba9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -9,7 +9,9 @@ - Bug in `io::write_using_write_byte`. - Bitstruct value cannot be used to index a const array in compile time. #2512 - Compiler fails to stop error print in recursive macro, and also prints unnecessary "inline at" #2513. -- Bitstruct truncated constant error escapes `$defined` #2515 +- Bitstruct truncated constant error escapes `$defined` #2515. +- Compiler segfault when accessing member of number cast to bitstruct #2516. +- Compiler assert when getting a member of a `bitstruct : char @bigendian` #2517. ### Stdlib changes diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index c0f09ba81..3696c219f 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1060,6 +1060,11 @@ static bool sema_analyse_bitstruct(SemaContext *context, Decl *decl, bool *erase DEBUG_LOG("Beginning analysis of %s.", decl->name ? decl->name : ".anon"); if (!sema_resolve_type_info(context, decl->strukt.container_type, RESOLVE_TYPE_DEFAULT)) return false; Type *type = type_flatten(decl->strukt.container_type->type->canonical); + if (type_size(type) == 1) + { + decl->strukt.big_endian = false; + decl->strukt.little_endian = false; + } Type *base_type = type->type_kind == TYPE_ARRAY ? type_flatten(type->array.base) : type; if (!type_is_integer(base_type)) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 2b0d5f68e..63ccfb26d 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -12046,18 +12046,20 @@ bool sema_cast_const(Expr *expr) { Expr *parent = expr->access_resolved_expr.parent; Type *flat = type_flatten(parent->type); + if (!sema_cast_const(parent)) return false; switch (flat->type_kind) { case TYPE_UNION: case TYPE_UNTYPED_LIST: - case TYPE_BITSTRUCT: case TYPE_STRUCT: break; + case TYPE_BITSTRUCT: + if (!expr_is_const_initializer(parent)) return false; + break; default: return false; } - if (!sema_cast_const(expr->access_resolved_expr.parent)) return false; - if (!sema_expr_fold_to_member(expr, expr->access_resolved_expr.parent, expr->access_resolved_expr.ref)) return false; + if (!sema_expr_fold_to_member(expr, parent, expr->access_resolved_expr.ref)) return false; return true; } case EXPR_SLICE: diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index cc9137af1..21a077d96 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -580,7 +580,7 @@ static inline bool sema_expr_analyse_initializer(SemaContext *context, Type *ass // 1. Designated initializer is separately evaluated. if (expr->expr_kind == EXPR_DESIGNATED_INITIALIZER_LIST) { - return sema_expr_analyse_designated_initializer(context, assigned_type, flattened, expr,NULL); + return sema_expr_analyse_designated_initializer(context, assigned_type, flattened, expr, no_match_ref); } if (expr->expr_kind == EXPR_CONST) diff --git a/test/test_suite/bitstruct/big_endian_char.c3t b/test/test_suite/bitstruct/big_endian_char.c3t new file mode 100644 index 000000000..a89f55bac --- /dev/null +++ b/test/test_suite/bitstruct/big_endian_char.c3t @@ -0,0 +1,16 @@ +bitstruct Instruction : char @bigendian +{ + ushort count : 4..7; +} + +bitstruct Instruction2 : char @littleendian +{ + ushort count : 4..7; +} + +fn int main(String[] args) +{ + Instruction a; + Instruction2 b; + return a.count; +} \ No newline at end of file diff --git a/test/test_suite/bitstruct/bitrstruct_defined.c3t b/test/test_suite/bitstruct/bitrstruct_defined.c3t index a9ab2e5b8..f412f1070 100644 --- a/test/test_suite/bitstruct/bitrstruct_defined.c3t +++ b/test/test_suite/bitstruct/bitrstruct_defined.c3t @@ -3,4 +3,5 @@ bitstruct Test : char char type : 0..2; } -$assert !$defined((Test){123}); \ No newline at end of file +$assert !$defined((Test){123}); +$assert !$defined((Test){.type = 123}); \ No newline at end of file diff --git a/test/test_suite/bitstruct/cast_bitstruct_as_const_value_fail.c3 b/test/test_suite/bitstruct/cast_bitstruct_as_const_value_fail.c3 new file mode 100644 index 000000000..ff1657b5e --- /dev/null +++ b/test/test_suite/bitstruct/cast_bitstruct_as_const_value_fail.c3 @@ -0,0 +1,8 @@ +bitstruct Test : char +{ + char type : 0..2; +} + +const TEST = ((Test)char.max).type; // #error: This expression cannot be evaluated at compile + +fn int main() => 0; \ No newline at end of file