From 1845a515cafa2d9961b89f6f3513c91add74c044 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 22 Jan 2026 21:39:03 +0100 Subject: [PATCH] - Empty ichar slice + byte concatenation hit an assert. #2789 --- releasenotes.md | 1 + src/compiler/sema_const.c | 2 ++ src/compiler/sema_initializers.c | 3 ++- test/test_suite/compile_time/concat_slice_cast.c3t | 5 +++++ 4 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/compile_time/concat_slice_cast.c3t diff --git a/releasenotes.md b/releasenotes.md index abfec8851..068682c32 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -107,6 +107,7 @@ - Recursive definition of tag not detected with nested tag/tagof #2790 - Attrdef eval environment lacked rtype, causing error on invalid args #2797 - $typeof() returns typeinfo, causing errors #2795. +- Empty ichar slice + byte concatenation hit an assert. #2789 ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/src/compiler/sema_const.c b/src/compiler/sema_const.c index 40bffc232..ee2b0cae1 100644 --- a/src/compiler/sema_const.c +++ b/src/compiler/sema_const.c @@ -146,6 +146,8 @@ static bool sema_concat_bytes_and_other(SemaContext *context, Expr *expr, Expr * ArraySize len = left->const_expr.bytes.len; bool is_bytes = left->const_expr.const_kind == CONST_BYTES; Type *indexed = type_get_indexed_type(left->type); + bool const_cast = sema_cast_const(right); + ASSERT(const_cast); const char *left_bytes = left->const_expr.bytes.ptr; RETRY:; switch (right->const_expr.const_kind) diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index d94436ee7..a4fe7c3bb 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -533,7 +533,8 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type if (!result) return false; bool is_bitmember = member && member->decl_kind == DECL_VAR && member->var.kind == VARDECL_BITMEMBER; Expr *value = expr->designator_expr.value; - if (!value && is_bitmember && member->var.start_bit == member->var.end_bit && type_flatten(result) == type_bool) { + if (!value && is_bitmember && member->var.start_bit == member->var.end_bit && type_flatten(result) == type_bool) + { ASSERT(is_bitstruct); value = expr_new_const_bool(INVALID_SPAN, type_bool, true); expr->designator_expr.value = value; diff --git a/test/test_suite/compile_time/concat_slice_cast.c3t b/test/test_suite/compile_time/concat_slice_cast.c3t new file mode 100644 index 000000000..cb3d840be --- /dev/null +++ b/test/test_suite/compile_time/concat_slice_cast.c3t @@ -0,0 +1,5 @@ +fn int main() +{ + const A = (ichar[]) { } +++ x'1234'; + return 0; +} \ No newline at end of file