From: Judah Caruso Date: Sun, 3 Dec 2023 22:49:29 +0000 (-0700) Subject: Fix array type building not handling unary expressions for arrays; add test X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=31734e339675e72d4c38a989e111d83891281eba;p=onyx.git Fix array type building not handling unary expressions for arrays; add test --- diff --git a/.gitignore b/.gitignore index 1fd5a472..83b48b21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/*.o +**/*.DS_Store *.o tags *.wasm diff --git a/compiler/src/astnodes.c b/compiler/src/astnodes.c index a8f12e1d..7665d68f 100644 --- a/compiler/src/astnodes.c +++ b/compiler/src/astnodes.c @@ -116,7 +116,7 @@ static const char* ast_node_names[] = { "FOREIGN BLOCK", "ZERO VALUE", - + "AST_NODE_KIND_COUNT", }; @@ -138,7 +138,7 @@ const char *binaryop_string[Binary_Op_Count] = { "|>", "..", "->", "[]", "[]=", "^[]", - + "??" }; @@ -772,7 +772,7 @@ TypeMatch unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) { return TYPE_MATCH_SUCCESS; } } - + // String literals implicitly become c-strings for convience. if (node->kind == Ast_Kind_StrLit && type->kind == Type_Kind_MultiPointer @@ -855,7 +855,7 @@ TypeMatch unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) { return TYPE_MATCH_SUCCESS; } - + if (match == TYPE_MATCH_YIELD) return TYPE_MATCH_YIELD; } @@ -1223,6 +1223,10 @@ i64 get_expression_integer_value(AstTyped* node, b32 *is_valid) { return get_expression_integer_value(((AstEnumValue *) node)->value, is_valid); } + if (node->kind == Ast_Kind_Unary_Op && type_is_integer(node->type)) { + return get_expression_integer_value(((AstUnaryOp *) node)->expr, is_valid); + } + if (node_is_type((AstNode*) node)) { Type* type = type_build_from_ast(context.ast_alloc, (AstType *) node); if (type) return type->id; @@ -1489,27 +1493,27 @@ TypeMatch implicit_cast_to_bool(AstTyped **pnode) { *pnode = (AstTyped *) cmp; return TYPE_MATCH_SUCCESS; } - + if (context.caches.implicit_cast_to_bool_cache.entries == NULL) { bh_imap_init(&context.caches.implicit_cast_to_bool_cache, global_heap_allocator, 8); } if (!bh_imap_has(&context.caches.implicit_cast_to_bool_cache, (u64) node)) { AstArgument *implicit_arg = make_argument(context.ast_alloc, node); - + Arguments *args = bh_alloc_item(context.ast_alloc, Arguments); bh_arr_new(context.ast_alloc, args->values, 1); bh_arr_push(args->values, (AstTyped *) implicit_arg); bh_imap_put(&context.caches.implicit_cast_to_bool_cache, (u64) node, (u64) args); } - + Arguments *args = (Arguments *) bh_imap_get(&context.caches.implicit_cast_to_bool_cache, (u64) node); AstFunction *overload = (AstFunction *) find_matching_overload_by_arguments(builtin_implicit_bool_cast->overloads, args); if (overload == NULL) return TYPE_MATCH_FAILED; if (overload == (AstFunction *) &node_that_signals_a_yield) return TYPE_MATCH_YIELD; - + AstCall *implicit_call = onyx_ast_node_new(context.ast_alloc, sizeof(AstCall), Ast_Kind_Call); implicit_call->token = node->token; implicit_call->callee = (AstTyped *) overload; diff --git a/compiler/src/types.c b/compiler/src/types.c index 9ebd494e..7aceffb4 100644 --- a/compiler/src/types.c +++ b/compiler/src/types.c @@ -378,7 +378,19 @@ static Type* type_build_from_ast_inner(bh_allocator alloc, AstType* type_node, b return NULL; } - count = get_expression_integer_value(a_node->count_expr, NULL); + b32 valid = 0; + count = get_expression_integer_value(a_node->count_expr, &valid); + + if (!valid) { + onyx_report_error(a_node->token->pos, Error_Critical, "Array type size expression must be 'i32', got '%s'.", + type_get_name(a_node->count_expr->type)); + return NULL; + } + + if ((i32)count < 0) { + onyx_report_error(a_node->token->pos, Error_Critical, "Array type size must be a positive integer."); + return NULL; + } } Type* array_type = type_make_array(alloc, elem_type, count); @@ -1129,7 +1141,7 @@ void build_linear_types_with_offset(Type* type, bh_arr(TypeWithOffset)* pdest, u build_linear_types_with_offset(type->Compound.types[i], pdest, offset + elem_offset); elem_offset += bh_max(type_size_of(type->Compound.types[i]), 4); } - + } else if (type->kind == Type_Kind_Slice || type->kind == Type_Kind_VarArgs || type->kind == Type_Kind_Function) { u32 mem_count = type_structlike_mem_count(type); StructMember smem = { 0 }; diff --git a/tests/bugs/array_lengths.onyx b/tests/bugs/array_lengths.onyx new file mode 100644 index 00000000..62c4e035 --- /dev/null +++ b/tests/bugs/array_lengths.onyx @@ -0,0 +1,29 @@ +#load "core/module" + +use core { * } + +An_Enum :: enum { + A; + B; + C; + D; + + Count; +} + +A_Struct :: struct { + a: i32; + b: i32; + c: i32; +} + +main :: () { + arr1: [cast(i32)(3 * 4 - 5)]f32; + arr2: [cast(i32)An_Enum.Count]A_Struct; + + assert(arr1.count == (3 * 4 - 5), "invalid count for arr1"); + assert(sizeof(typeof(arr1)) == (3 * 4 - 5) * sizeof(f32), "invalid size for arr1"); + + assert(arr2.count == ~~An_Enum.Count, "invalid count for arr2"); + assert(sizeof(typeof(arr2)) == ~~An_Enum.Count * sizeof(A_Struct), "invalid size for arr2"); +}