- Compiler segfault when accessing member of number cast to bitstruct #2516.

- Additional fix to #2515
- Compiler assert when getting a member of a `bitstruct : char @bigendian` #2517.
This commit is contained in:
Christoffer Lerno
2025-10-07 00:12:41 +02:00
parent b4b14674b4
commit 04cd079d4e
7 changed files with 40 additions and 6 deletions

View File

@@ -9,7 +9,9 @@
- Bug in `io::write_using_write_byte`. - Bug in `io::write_using_write_byte`.
- Bitstruct value cannot be used to index a const array in compile time. #2512 - 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. - 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 ### Stdlib changes

View File

@@ -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"); 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; 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); 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; Type *base_type = type->type_kind == TYPE_ARRAY ? type_flatten(type->array.base) : type;
if (!type_is_integer(base_type)) if (!type_is_integer(base_type))
{ {

View File

@@ -12046,18 +12046,20 @@ bool sema_cast_const(Expr *expr)
{ {
Expr *parent = expr->access_resolved_expr.parent; Expr *parent = expr->access_resolved_expr.parent;
Type *flat = type_flatten(parent->type); Type *flat = type_flatten(parent->type);
if (!sema_cast_const(parent)) return false;
switch (flat->type_kind) switch (flat->type_kind)
{ {
case TYPE_UNION: case TYPE_UNION:
case TYPE_UNTYPED_LIST: case TYPE_UNTYPED_LIST:
case TYPE_BITSTRUCT:
case TYPE_STRUCT: case TYPE_STRUCT:
break; break;
case TYPE_BITSTRUCT:
if (!expr_is_const_initializer(parent)) return false;
break;
default: default:
return false; return false;
} }
if (!sema_cast_const(expr->access_resolved_expr.parent)) return false; if (!sema_expr_fold_to_member(expr, parent, expr->access_resolved_expr.ref)) return false;
if (!sema_expr_fold_to_member(expr, expr->access_resolved_expr.parent, expr->access_resolved_expr.ref)) return false;
return true; return true;
} }
case EXPR_SLICE: case EXPR_SLICE:

View File

@@ -580,7 +580,7 @@ static inline bool sema_expr_analyse_initializer(SemaContext *context, Type *ass
// 1. Designated initializer is separately evaluated. // 1. Designated initializer is separately evaluated.
if (expr->expr_kind == EXPR_DESIGNATED_INITIALIZER_LIST) 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) if (expr->expr_kind == EXPR_CONST)

View File

@@ -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;
}

View File

@@ -3,4 +3,5 @@ bitstruct Test : char
char type : 0..2; char type : 0..2;
} }
$assert !$defined((Test){123}); $assert !$defined((Test){123});
$assert !$defined((Test){.type = 123});

View File

@@ -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;