From 5e23817a3de7ba5b2cc813f3006a9efd9b63a177 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 24 Jan 2026 17:57:56 +0100 Subject: [PATCH] - Comparing a flexible array member to another type would hit an assert. #2830 - Underlying slice type not checked correctly in $defined #2829 - Checking for exhaustive cases is done even in if-chain switch if all is enum #2828 --- releasenotes.md | 3 +++ src/compiler/sema_expr.c | 21 +++++++++++++++++++ src/compiler/sema_stmts.c | 2 +- src/compiler/types.c | 5 +++++ .../defined_slice_invalid_type.c3 | 4 ++++ .../defined_slice_invalid_type2.c3 | 5 +++++ .../defined_slice_invalid_type3.c3 | 4 ++++ .../enum_exhaustive_check_if_chain.c3 | 12 +++++++++++ test/test_suite/struct/flex_array_max_type.c3 | 10 +++++++++ 9 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/compile_time_introspection/defined_slice_invalid_type.c3 create mode 100644 test/test_suite/compile_time_introspection/defined_slice_invalid_type2.c3 create mode 100644 test/test_suite/compile_time_introspection/defined_slice_invalid_type3.c3 create mode 100644 test/test_suite/enumerations/enum_exhaustive_check_if_chain.c3 create mode 100644 test/test_suite/struct/flex_array_max_type.c3 diff --git a/releasenotes.md b/releasenotes.md index ab0fd10f2..a764adb0c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -110,6 +110,9 @@ - $typeof() returns typeinfo, causing errors #2795. - Empty ichar slice + byte concatenation hit an assert. #2789 - Remove dependency on test tmp library for stdlib compiler tests. #2800 +- Comparing a flexible array member to another type would hit an assert. #2830 +- Underlying slice type not checked correctly in $defined #2829 +- Checking for exhaustive cases is done even in if-chain switch if all is enum #2828 ### 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_expr.c b/src/compiler/sema_expr.c index bf72299d2..b042d6bf6 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -10564,6 +10564,13 @@ RETRY: Type *type = sema_expr_check_type_exists(context, type_info->array.base); if (!type) return NULL; if (!type_ok(type)) return type; + if (!type_is_valid_for_array(type)) + { + SEMA_ERROR(type_info->array.base, + "You cannot form a slice with elements of type %s.", + type_quoted_error_string(type)); + return poisoned_type; + } return type_get_slice(type); } case TYPE_INFO_INFERRED_ARRAY: @@ -10572,6 +10579,13 @@ RETRY: Type *type = sema_expr_check_type_exists(context, type_info->array.base); if (!type) return NULL; if (!type_ok(type)) return type; + if (!type_is_valid_for_array(type)) + { + SEMA_ERROR(type_info->array.base, + "You cannot form an array with elements of type %s.", + type_quoted_error_string(type)); + return poisoned_type; + } return type_get_inferred_array(type); } case TYPE_INFO_INFERRED_VECTOR: @@ -10580,6 +10594,13 @@ RETRY: Type *type = sema_expr_check_type_exists(context, type_info->array.base); if (!type) return NULL; if (!type_ok(type)) return type; + if (!type_is_valid_for_vector(type)) + { + SEMA_ERROR(type_info->array.base, + "%s is not of a vectorizable type.", + type_quoted_error_string(type)); + return poisoned_type; + } return type_get_inferred_vector(type); } case TYPE_INFO_POINTER: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 971b46d33..5bd329a93 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2648,7 +2648,7 @@ FOUND:; all_jump_end &= context->active_scope.end_jump.active; SCOPE_END; } - if (is_enum_switch && !exhaustive && success) + if (is_enum_switch && !exhaustive && success && !if_chain) { RETURN_SEMA_ERROR(statement, create_missing_enums_in_switch_error(cases, actual_enum_cases, enum_values)); } diff --git a/src/compiler/types.c b/src/compiler/types.c index ec36de9bf..b1e9c3978 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -1066,6 +1066,10 @@ Type *type_get_optional(Type *optional_type) Type *type_get_slice(Type *arr_type) { + if (!type_is_valid_for_array(arr_type)) + { + puts("ofek"); + } ASSERT(type_is_valid_for_array(arr_type)); return type_generate_slice(arr_type, false); } @@ -2273,6 +2277,7 @@ RETRY_DISTINCT: // array + [other array, vector] => no return NULL; case TYPE_FLEXIBLE_ARRAY: + return NULL; case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: // Already handled diff --git a/test/test_suite/compile_time_introspection/defined_slice_invalid_type.c3 b/test/test_suite/compile_time_introspection/defined_slice_invalid_type.c3 new file mode 100644 index 000000000..edab0ed14 --- /dev/null +++ b/test/test_suite/compile_time_introspection/defined_slice_invalid_type.c3 @@ -0,0 +1,4 @@ +fn void test1() +{ + bool a = $defined(void[]); // #error: You cannot form a slice with elements of type +} diff --git a/test/test_suite/compile_time_introspection/defined_slice_invalid_type2.c3 b/test/test_suite/compile_time_introspection/defined_slice_invalid_type2.c3 new file mode 100644 index 000000000..756b44ead --- /dev/null +++ b/test/test_suite/compile_time_introspection/defined_slice_invalid_type2.c3 @@ -0,0 +1,5 @@ + +fn void test2() +{ + bool b = $defined(void[*]); // #error: You cannot form an array with elements of type +} diff --git a/test/test_suite/compile_time_introspection/defined_slice_invalid_type3.c3 b/test/test_suite/compile_time_introspection/defined_slice_invalid_type3.c3 new file mode 100644 index 000000000..db10cb3df --- /dev/null +++ b/test/test_suite/compile_time_introspection/defined_slice_invalid_type3.c3 @@ -0,0 +1,4 @@ +fn void test1() +{ + bool a = $defined(void[<*>]); // #error: 'void' is not of a vectorizable type +} diff --git a/test/test_suite/enumerations/enum_exhaustive_check_if_chain.c3 b/test/test_suite/enumerations/enum_exhaustive_check_if_chain.c3 new file mode 100644 index 000000000..ef3a3f437 --- /dev/null +++ b/test/test_suite/enumerations/enum_exhaustive_check_if_chain.c3 @@ -0,0 +1,12 @@ +enum Baz +{ + A, B, C, +} +fn void test_missing_all_cases(Baz x) +{ + switch (x) + { + case x: + } +} +fn int main() => 0; \ No newline at end of file diff --git a/test/test_suite/struct/flex_array_max_type.c3 b/test/test_suite/struct/flex_array_max_type.c3 new file mode 100644 index 000000000..434ef7c04 --- /dev/null +++ b/test/test_suite/struct/flex_array_max_type.c3 @@ -0,0 +1,10 @@ +struct Abc +{ + int x; + int[*] y; +} +fn void test() +{ + Abc y; + bool same = Abc.y == y.y; // #error: 'member_ref' and 'int[*]' are different types and cannot be compared +} \ No newline at end of file