diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index c08bbb43c..c4c973f92 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2141,7 +2141,7 @@ bool cast_explicit(SemaContext *context, Expr *expr, Type *to_type); bool may_cast(SemaContext *cc, Expr *expr, Type *to_type, bool is_explicit, bool is_silent); -void cast_no_check(SemaContext *context, Expr *expr, Type *to_type, bool add_optional); +void cast_no_check(Expr *expr, Type *to_type, bool add_optional); bool cast_to_index(SemaContext *context, Expr *index, Type *subscripted_type); @@ -2337,7 +2337,7 @@ Expr **sema_expand_vasplat_exprs(SemaContext *context, Expr **exprs); bool sema_expr_analyse_general_call(SemaContext *context, Expr *expr, Decl *decl, Expr *struct_var, bool optional, bool *no_match_ref); -void sema_expr_convert_enum_to_int(SemaContext *context, Expr *expr); +void sema_expr_convert_enum_to_int(Expr *expr); Decl *sema_decl_stack_resolve_symbol(const char *symbol); Decl *sema_find_decl_in_modules(Module **module_list, Path *path, const char *interned_name); bool unit_resolve_parameterized_symbol(SemaContext *context, NameResolve *name_resolve); diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 845944118..a04f0caea 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -24,8 +24,8 @@ typedef struct static bool sema_error_const_int_out_of_range(CastContext *cc, Expr *expr, Expr *problem, Type *to_type); static Expr *recursive_may_narrow(Expr *expr, Type *type); -static void expr_recursively_rewrite_untyped_list(Expr *expr, Expr **list); -static void vector_const_initializer_convert_to_type(SemaContext *context, ConstInitializer *initializer, Type *to_type); +static void expr_recursively_rewrite_untyped_list(Expr *expr, Type *to_type); +static void vector_const_initializer_convert_to_type(ConstInitializer *initializer, Type *to_type); static bool cast_is_allowed(CastContext *cc, bool is_explicit, bool is_silent); static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent, @@ -35,7 +35,7 @@ INLINE void cast_context_set_from(CastContext *cc, Type *new_from); INLINE void cast_context_set_to(CastContext *cc, Type *new_to); typedef bool(*CastRule)(CastContext *cc, bool is_explicit, bool is_silent); -typedef void(*CastFunction)(SemaContext *context, Expr *expr, Type *to_type); +typedef void(*CastFunction)(Expr *expr, Type *to_type); extern CastFunction cast_function[CONV_LAST + 1][CONV_LAST + 1]; extern CastRule cast_rules[CONV_LAST + 1][CONV_LAST + 1]; @@ -122,7 +122,7 @@ static bool cast_is_allowed(CastContext *cc, bool is_explicit, bool is_silent) /** * Perform the cast with no additional checks. Casting from untyped not allowed. */ -void cast_no_check(SemaContext *context, Expr *expr, Type *to_type, bool add_optional) +void cast_no_check(Expr *expr, Type *to_type, bool add_optional) { Type *to = type_flatten(to_type); Type *from = type_flatten(expr->type); @@ -136,7 +136,7 @@ void cast_no_check(SemaContext *context, Expr *expr, Type *to_type, bool add_opt CastFunction func = cast_function[from_group][to_group]; if (func) { - func(context, expr, to_type); + func(expr, to_type); expr->type = type_add_optional(expr->type, add_optional); return; } @@ -147,7 +147,7 @@ void cast_no_check(SemaContext *context, Expr *expr, Type *to_type, bool add_opt * Given lhs and rhs, promote to the maximum bit size, this will retain * signed/unsigned type of each side. */ -void cast_to_int_to_max_bit_size(SemaContext *context, Expr *lhs, Expr *rhs, Type *left_type, Type *right_type) +void cast_to_int_to_max_bit_size(Expr *lhs, Expr *rhs, Type *left_type, Type *right_type) { unsigned bit_size_left = left_type->builtin.bitsize; unsigned bit_size_right = right_type->builtin.bitsize; @@ -164,7 +164,7 @@ void cast_to_int_to_max_bit_size(SemaContext *context, Expr *lhs, Expr *rhs, Typ Type *to = lhs->type->type_kind < TYPE_U8 ? type_int_signed_by_bitsize(bit_size_right) : type_int_unsigned_by_bitsize(bit_size_right); - cast_no_check(context, lhs, to, IS_OPTIONAL(lhs)); + cast_no_check(lhs, to, IS_OPTIONAL(lhs)); return; } @@ -172,7 +172,7 @@ void cast_to_int_to_max_bit_size(SemaContext *context, Expr *lhs, Expr *rhs, Typ Type *to = rhs->type->type_kind < TYPE_U8 ? type_int_signed_by_bitsize(bit_size_left) : type_int_unsigned_by_bitsize(bit_size_left); - cast_no_check(context, rhs, to, IS_OPTIONAL(rhs)); + cast_no_check(rhs, to, IS_OPTIONAL(rhs)); } /** @@ -181,7 +181,7 @@ void cast_to_int_to_max_bit_size(SemaContext *context, Expr *lhs, Expr *rhs, Typ * 2. Widen float and smaller to double * 3. Turn slices into pointers */ -void cast_promote_vararg(SemaContext *context, Expr *arg) +void cast_promote_vararg(Expr *arg) { // Remove things like distinct, optional, enum etc. Type *arg_type = type_flatten(arg->type); @@ -189,21 +189,21 @@ void cast_promote_vararg(SemaContext *context, Expr *arg) // 1. Promote any integer or bool to at least CInt if (type_is_promotable_int_bool(arg_type)) { - cast_no_check(context, arg, type_cint, IS_OPTIONAL(arg)); + cast_no_check(arg, type_cint, IS_OPTIONAL(arg)); return; } // 2. Promote any float to at least double if (type_is_promotable_float(arg_type)) { - cast_no_check(context, arg, type_double, IS_OPTIONAL(arg)); + cast_no_check(arg, type_double, IS_OPTIONAL(arg)); return; } // 3. Turn slices into pointers if (arg_type->type_kind == TYPE_SLICE) { - cast_no_check(context, arg, type_get_ptr(arg_type->array.base), IS_OPTIONAL(arg)); + cast_no_check(arg, type_get_ptr(arg_type->array.base), IS_OPTIONAL(arg)); return; } @@ -316,7 +316,7 @@ static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool return false; } - cast_no_check(context, expr, to_type, add_optional); + cast_no_check(expr, to_type, add_optional); return true; } @@ -524,16 +524,84 @@ static bool sema_error_const_int_out_of_range(CastContext *cc, Expr *expr, Expr /** * Recursively change a const list to an initializer list. */ -static void expr_recursively_rewrite_untyped_list(Expr *expr, Expr **list) +static void expr_recursively_rewrite_untyped_list(Expr *expr, Type *to_type) { - if (!expr_is_const_untyped_list(expr)) return; - expr->expr_kind = EXPR_INITIALIZER_LIST; - expr->initializer_list = list; - expr->resolve_status = RESOLVE_NOT_DONE; - FOREACH(Expr *, inner, list) + ASSERT_SPAN(expr, expr_is_const_untyped_list(expr)); + expr->expr_kind = EXPR_CONST; + Expr **values = expr->const_expr.untyped_list; + unsigned count = vec_size(values); + ConstInitializer **elements = NULL; + Type *flat = type_flatten(to_type); + bool is_slice = flat->type_kind == TYPE_SLICE; + if (type_is_inferred(flat)) { - expr_recursively_rewrite_untyped_list(inner, inner->const_expr.untyped_list); + assert(vec_size(values) > 0); + to_type = type_from_inferred(flat, type_get_indexed_type(to_type), vec_size(values)); + flat = type_flatten(to_type); } + // Handle {} + if (!count) + { + if (is_slice) + { + expr_rewrite_const_slice(expr, to_type, NULL); + return; + } + expr_rewrite_const_initializer(expr, to_type, const_init_new_zero(flat)); + return; + } + switch (flat->type_kind) + { + case TYPE_VECTOR: + { + Type *indexed = type_get_indexed_type(to_type); + FOREACH(Expr *, e, values) + { + vec_add(elements, const_init_new_value(e)); + cast_no_check(e, indexed, false); + } + expr_rewrite_const_initializer(expr, to_type, const_init_new_array_full(flat, elements)); + return; + } + case TYPE_SLICE: + case TYPE_ARRAY: + { + Type *indexed = type_get_indexed_type(to_type); + FOREACH(Expr *, e, values) + { + if (e->type == type_untypedlist) + { + expr_recursively_rewrite_untyped_list(e, indexed); + } + cast_no_check(e, indexed, false); + vec_add(elements, const_init_new_value(e)); + } + if (is_slice) + { + expr_rewrite_const_slice(expr, to_type, const_init_new_array_full(type_get_array(indexed, count), elements)); + return; + } + expr_rewrite_const_initializer(expr, to_type, const_init_new_array_full(to_type, elements)); + return; + } + case TYPE_STRUCT: + break; + default: + UNREACHABLE + } + Decl *decl = flat->decl; + Decl **members = decl->strukt.members; + + FOREACH_IDX(idx, Expr *, e, values) + { + Type *type = members[idx]->type; + if (e->type == type_untypedlist) + { + expr_recursively_rewrite_untyped_list(e, type); + } + cast_no_check(e, type, false); + } + expr_rewrite_const_initializer(expr, to_type, const_init_new_struct(flat, values)); } @@ -623,27 +691,24 @@ static bool report_cast_error(CastContext *cc, bool may_cast_explicit) type_quoted_error_string(to), type_to_error_string(type_no_optional(to))); } - else + if (to->type_kind == TYPE_INTERFACE) { - if (to->type_kind == TYPE_INTERFACE) + if (expr->type->canonical->type_kind != TYPE_POINTER) { - if (expr->type->canonical->type_kind != TYPE_POINTER) - { - RETURN_CAST_ERROR(expr, - "You can only convert pointers to an interface like %s. " - "Try passing the address of the expression instead.", - type_quoted_error_string(to)); - } + RETURN_CAST_ERROR(expr, + "You can only convert pointers to an interface like %s. " + "Try passing the address of the expression instead.", + type_quoted_error_string(to)); } - else if (to->type_kind == TYPE_ANY && expr->type->canonical->type_kind != TYPE_POINTER) - { - RETURN_CAST_ERROR(expr, "You can only convert pointers to 'any'. " - "Try passing the address of the expression instead."); - } - RETURN_CAST_ERROR(expr, - "It is not possible to cast %s to %s.", - type_quoted_error_string(type_no_optional(expr->type)), type_quoted_error_string(to)); } + if (to->type_kind == TYPE_ANY && expr->type->canonical->type_kind != TYPE_POINTER) + { + RETURN_CAST_ERROR(expr, "You can only convert pointers to 'any'. " + "Try passing the address of the expression instead."); + } + RETURN_CAST_ERROR(expr, + "It is not possible to cast %s to %s.", + type_quoted_error_string(type_no_optional(expr->type)), type_quoted_error_string(to)); } INLINE bool sema_cast_error(CastContext *cc, bool may_cast_explicit, bool is_silent) @@ -786,7 +851,7 @@ static bool rule_arrptr_to_slice(CastContext *cc, bool is_explicit, bool is_sile return sema_cast_error(cc, may_explicit, is_silent); } -static bool rule_ulist_to_struct(CastContext *cc, bool is_explicit, bool is_silent) +static bool rule_ulist_to_struct(CastContext *cc, UNUSED bool is_explicit, bool is_silent) { ASSERT(expr_is_const_untyped_list(cc->expr)); Expr **expressions = cc->expr->const_expr.untyped_list; @@ -1394,7 +1459,7 @@ static bool rule_bits_to_int(CastContext *cc, bool is_explicit, bool is_silent) // CASTS ---- -static void cast_vaptr_to_slice(SemaContext *context, Expr *expr, Type *type) +static void cast_vaptr_to_slice(Expr *expr, Type *type) { Type *flat = type_flatten(expr->type); ASSERT(flat->type_kind == TYPE_POINTER); @@ -1407,7 +1472,7 @@ static void cast_vaptr_to_slice(SemaContext *context, Expr *expr, Type *type) expr->type = type; } -static void cast_ptr_to_any(SemaContext *context, Expr *expr, Type *type) +static void cast_ptr_to_any(Expr *expr, Type *type) { Expr *inner = expr_copy(expr); Expr *typeid = expr_copy(expr); @@ -1416,21 +1481,23 @@ static void cast_ptr_to_any(SemaContext *context, Expr *expr, Type *type) expr->make_any_expr = (ExprMakeAny) { .inner = inner, .typeid = typeid }; expr->type = type; } -static void cast_struct_to_inline(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_addr_conversion(expr, type); } -static void cast_fault_to_anyfault(SemaContext *context, Expr *expr, Type *type) { expr->type = type; }; -static void cast_fault_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_to_int_to_ptr(expr, type); } -static void cast_typeid_to_int(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_ext_trunc(expr, type, type_is_signed(type_flatten_to_int(type))); } -static void cast_fault_to_int(SemaContext *context, Expr *expr, Type *type) { cast_typeid_to_int(context, expr, type); } -static void cast_typeid_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_to_int_to_ptr(expr, type); } -static void cast_any_to_bool(SemaContext *context, Expr *expr, Type *type) { +static void cast_struct_to_inline(Expr *expr, Type *type) { expr_rewrite_addr_conversion(expr, type); } +static void cast_fault_to_anyfault(Expr *expr, Type *type) { expr->type = type; }; +static void cast_fault_to_ptr(Expr *expr, Type *type) { expr_rewrite_to_int_to_ptr(expr, type); } +static void cast_typeid_to_int(Expr *expr, Type *type) { expr_rewrite_ext_trunc(expr, type, type_is_signed(type_flatten_to_int(type))); } +static void cast_fault_to_int(Expr *expr, Type *type) { cast_typeid_to_int(expr, type); } +static void cast_typeid_to_ptr(Expr *expr, Type *type) { expr_rewrite_to_int_to_ptr(expr, type); } +static void cast_any_to_bool(Expr *expr, Type *type) +{ expr_rewrite_ptr_access(expr, expr_copy(expr), type_voidptr); expr_rewrite_int_to_bool(expr, false); + expr->type = type; } -static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_ptr_access(expr, expr_copy(expr), type); } -static void cast_all_to_void(SemaContext *context, Expr *expr, Type *to_type) { expr_rewrite_discard(expr); } -static void cast_retype(SemaContext *context, Expr *expr, Type *to_type) { expr->type = to_type; } +static void cast_any_to_ptr(Expr *expr, Type *type) { expr_rewrite_ptr_access(expr, expr_copy(expr), type); } +static void cast_all_to_void(Expr *expr, UNUSED Type *to_type) { expr_rewrite_discard(expr); } +static void cast_retype(Expr *expr, Type *to_type) { expr->type = to_type; } -static void vector_const_initializer_convert_to_type(SemaContext *context, ConstInitializer *initializer, Type *to_type) +static void vector_const_initializer_convert_to_type(ConstInitializer *initializer, Type *to_type) { switch (initializer->kind) { @@ -1439,7 +1506,7 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const Type *element_type = type_flatten(to_type)->array.base; FOREACH(ConstInitializer *, element, initializer->init_array.elements) { - vector_const_initializer_convert_to_type(context, element, element_type); + vector_const_initializer_convert_to_type(element, element_type); } break; } @@ -1448,7 +1515,7 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const Type *element_type = type_flatten(to_type)->array.base; FOREACH(ConstInitializer *, element, initializer->init_array_full) { - vector_const_initializer_convert_to_type(context, element, element_type); + vector_const_initializer_convert_to_type(element, element_type); } break; } @@ -1468,7 +1535,7 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const } else { - cast_no_check(context, initializer->init_value, to_type, IS_OPTIONAL(initializer->init_value)); + cast_no_check(initializer->init_value, to_type, IS_OPTIONAL(initializer->init_value)); } break; } @@ -1478,7 +1545,7 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const case CONST_INIT_STRUCT: UNREACHABLE case CONST_INIT_ARRAY_VALUE: - vector_const_initializer_convert_to_type(context, initializer->init_array_value.element, to_type); + vector_const_initializer_convert_to_type(initializer->init_array_value.element, to_type); break; } initializer->type = type_flatten(to_type); @@ -1487,7 +1554,7 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const /** * Insert a PTRPTR cast or update the pointer type */ -static void cast_ptr_to_ptr(SemaContext *context, Expr *expr, Type *type) +static void cast_ptr_to_ptr(Expr *expr, Type *type) { if (!sema_cast_const(expr) || expr->const_expr.const_kind == CONST_STRING) { @@ -1504,7 +1571,7 @@ static void cast_ptr_to_ptr(SemaContext *context, Expr *expr, Type *type) /** * Convert any fp to another fp type using CAST_FPFP */ -static void cast_float_to_float(SemaContext *context, Expr *expr, Type *type) +static void cast_float_to_float(Expr *expr, Type *type) { // Change to same type should never enter here. ASSERT(type_flatten(type) != type_flatten(expr->type)); @@ -1524,7 +1591,7 @@ static void cast_float_to_float(SemaContext *context, Expr *expr, Type *type) * Convert from any floating point to int using CAST_FPINT * Const conversion will disable narrowable and hex. */ -static void cast_float_to_int(SemaContext *context, Expr *expr, Type *type) +static void cast_float_to_int(Expr *expr, Type *type) { if (!sema_cast_const(expr)) { @@ -1546,7 +1613,7 @@ static void cast_float_to_int(SemaContext *context, Expr *expr, Type *type) * Convert from integer to enum using CAST_INTENUM / or do a const conversion. * This will ensure that the conversion is valid (i.e. in the range 0 .. enumcount - 1) */ -static void cast_int_to_enum(SemaContext *context, Expr *expr, Type *type) +static void cast_int_to_enum(Expr *expr, Type *type) { static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "Using casts to convert integers to enums is deprecated in favour of using 'MyEnum.from_ordinal(i)`."); @@ -1574,7 +1641,7 @@ static void cast_int_to_enum(SemaContext *context, Expr *expr, Type *type) /** * Convert between integers: CAST_INTINT */ -static void cast_int_to_int(SemaContext *context, Expr *expr, Type *type) +static void cast_int_to_int(Expr *expr, Type *type) { // Fold pointer casts if narrowing // So (int)(uptr)&x => (int)&x in the backend. @@ -1603,11 +1670,11 @@ static void cast_int_to_int(SemaContext *context, Expr *expr, Type *type) /** * Convert 1 => { 1, 1, 1, 1 } using CAST_EXPVEC */ -static void cast_expand_to_vec(SemaContext *context, Expr *expr, Type *type) +static void cast_expand_to_vec(Expr *expr, Type *type) { // Fold pointer casts if narrowing Type *base = type_get_indexed_type(type); - cast_no_check(context, expr, base, IS_OPTIONAL(expr)); + cast_no_check(expr, base, IS_OPTIONAL(expr)); Expr *inner = expr_copy(expr); expr->expr_kind = EXPR_SCALAR_TO_VECTOR; expr->inner_expr = inner; @@ -1615,10 +1682,10 @@ static void cast_expand_to_vec(SemaContext *context, Expr *expr, Type *type) expr->resolve_status = RESOLVE_DONE; } -static void cast_bitstruct_to_int_arr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_recast(expr, type); } -static void cast_int_arr_to_bitstruct(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_recast(expr, type); } +static void cast_bitstruct_to_int_arr(Expr *expr, Type *type) { expr_rewrite_recast(expr, type); } +static void cast_int_arr_to_bitstruct(Expr *expr, Type *type) { expr_rewrite_recast(expr, type); } -static void cast_bitstruct_to_bool(SemaContext *context, Expr *expr, Type *type) +static void cast_bitstruct_to_bool(Expr *expr, Type *type) { expr_rewrite_int_to_bool(expr, false); expr->type = type; @@ -1629,7 +1696,7 @@ static void cast_bitstruct_to_bool(SemaContext *context, Expr *expr, Type *type) * Cast a signed or unsigned integer -> floating point, using CAST_INTFP * for runtime, otherwise do const transformation. */ -static void cast_int_to_float(SemaContext *context, Expr *expr, Type *type) +static void cast_int_to_float(Expr *expr, Type *type) { if (!sema_cast_const(expr)) { @@ -1641,19 +1708,19 @@ static void cast_int_to_float(SemaContext *context, Expr *expr, Type *type) expr_rewrite_const_float(expr, type, f); } -static void cast_enum_to_int(SemaContext *context, Expr* expr, Type *to_type) +static void cast_enum_to_int(Expr* expr, Type *to_type) { static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "Using casts to convert enums to integers is deprecated in favour of using 'the_enum.ordinal`."); - sema_expr_convert_enum_to_int(context, expr); - cast_int_to_int(context, expr, to_type); + sema_expr_convert_enum_to_int(expr); + cast_int_to_int(expr, to_type); } /** * Cast using CAST_VECARR, casting an array to a vector. For the constant, this * is a simple type change, see array_to_vec. */ -static void cast_vec_to_arr(SemaContext *context, Expr *expr, Type *to_type) +static void cast_vec_to_arr(Expr *expr, Type *to_type) { if (!sema_cast_const(expr)) { @@ -1674,7 +1741,7 @@ static void cast_vec_to_arr(SemaContext *context, Expr *expr, Type *to_type) * Convert vector -> vector. This is somewhat complex as there are various functions * we need to invoke depending on the underlying type. */ -static void cast_vec_to_vec(SemaContext *context, Expr *expr, Type *to_type) +static void cast_vec_to_vec(Expr *expr, Type *to_type) { if (!sema_cast_const(expr)) { @@ -1788,24 +1855,19 @@ static void cast_vec_to_vec(SemaContext *context, Expr *expr, Type *to_type) // For the const initializer we need to change the internal type ConstInitializer *list = expr->const_expr.initializer; - vector_const_initializer_convert_to_type(context, list, to_type); + vector_const_initializer_convert_to_type(list, to_type); expr->type = to_type; } -static void cast_untyped_list_to_other(SemaContext *context, Expr *expr, Type *to_type) +static void cast_untyped_list_to_other(Expr *expr, Type *to_type) { ASSERT(expr_is_const_untyped_list(expr)); // Recursively set the type of all ConstInitializer inside. - expr_recursively_rewrite_untyped_list(expr, expr->const_expr.untyped_list); - // We can now analyse the list (this is where the actual check happens) - bool success = sema_expr_analyse_initializer_list(context, type_flatten(to_type), expr); - ASSERT(success); - // And set the type. - expr->type = type_infer_len_from_actual_type(to_type, expr->type); + expr_recursively_rewrite_untyped_list(expr, to_type); } -static void cast_anyfault_to_fault(SemaContext *context, Expr *expr, Type *type) +static void cast_anyfault_to_fault(Expr *expr, Type *type) { if (!sema_cast_const(expr)) { @@ -1821,7 +1883,7 @@ static void cast_anyfault_to_fault(SemaContext *context, Expr *expr, Type *type) expr->type = type; } -static void cast_slice_to_ptr(SemaContext *context, Expr *expr, Type *type) +static void cast_slice_to_ptr(Expr *expr, Type *type) { if (expr_is_const_string(expr) || expr_is_const_bytes(expr)) { @@ -1836,7 +1898,7 @@ static void cast_slice_to_ptr(SemaContext *context, Expr *expr, Type *type) * Cast any int to a pointer, will use CAST_INTPTR after a conversion to uptr for runtime. * Compile time it will check that the value fits the pointer size. */ -static void cast_int_to_ptr(SemaContext *context, Expr *expr, Type *type) +static void cast_int_to_ptr(Expr *expr, Type *type) { ASSERT(type_bit_size(type_uptr) <= 64 && "For > 64 bit pointers, this code needs updating."); @@ -1849,7 +1911,7 @@ static void cast_int_to_ptr(SemaContext *context, Expr *expr, Type *type) return; } // This may be a narrowing - cast_no_check(context, expr, type_uptr, IS_OPTIONAL(expr)); + cast_no_check(expr, type_uptr, IS_OPTIONAL(expr)); expr_rewrite_to_int_to_ptr(expr, type); } @@ -1857,14 +1919,13 @@ static void cast_int_to_ptr(SemaContext *context, Expr *expr, Type *type) * Bool into a signed or unsigned int using CAST_BOOLINT * or rewrite to 0 / 1 for false / true. */ -static void cast_bool_to_int(SemaContext *context, Expr *expr, Type *type) +static void cast_bool_to_int(Expr *expr, Type *type) { if (!sema_cast_const(expr)) { expr_rewrite_ext_trunc(expr, type, false); return; } - expr_rewrite_const_int(expr, type, expr->const_expr.b ? 1 : 0); } @@ -1873,7 +1934,7 @@ static void cast_bool_to_int(SemaContext *context, Expr *expr, Type *type) * Cast bool to float using CAST_BOOLFP * or rewrite to 0.0 / 1.0 for false / true */ -static void cast_bool_to_float(SemaContext *context, Expr *expr, Type *type) +static void cast_bool_to_float(Expr *expr, Type *type) { if (!sema_cast_const(expr)) { @@ -1889,7 +1950,7 @@ static void cast_bool_to_float(SemaContext *context, Expr *expr, Type *type) * Cast int to bool using CAST_INTBOOL * or rewrite 0 => false, any other value => true */ -static void cast_int_to_bool(SemaContext *context, Expr *expr, Type *type) +static void cast_int_to_bool(Expr *expr, Type *type) { if (!expr_is_const(expr)) { @@ -1905,7 +1966,7 @@ static void cast_int_to_bool(SemaContext *context, Expr *expr, Type *type) * Cast any float to bool using CAST_FPBOOL * or rewrite 0.0 => false, any other value => true */ -static void cast_float_to_bool(SemaContext *context, Expr *expr, Type *type) +static void cast_float_to_bool(Expr *expr, Type *type) { if (!expr_is_const(expr)) { @@ -1926,7 +1987,7 @@ static void cast_float_to_bool(SemaContext *context, Expr *expr, Type *type) /** * Insert the PTRXI cast, or on const do a rewrite. */ -static void cast_ptr_to_int(SemaContext *context, Expr *expr, Type *type) +static void cast_ptr_to_int(Expr *expr, Type *type) { if (sema_cast_const(expr) && expr_is_const_pointer(expr)) { @@ -1940,7 +2001,7 @@ static void cast_ptr_to_int(SemaContext *context, Expr *expr, Type *type) /** * Insert the PTRBOOL cast or on const do a rewrite. */ -static void cast_ptr_to_bool(SemaContext *context, Expr *expr, Type *type) +static void cast_ptr_to_bool(Expr *expr, Type *type) { if (!expr_is_const(expr)) { @@ -1969,7 +2030,7 @@ static void cast_ptr_to_bool(SemaContext *context, Expr *expr, Type *type) } -static void cast_slice_to_bool(SemaContext *context, Expr *expr, Type *type) +static void cast_slice_to_bool(Expr *expr, Type *type) { if (expr_is_const_string(expr) || expr_is_const_bytes(expr)) { @@ -1993,7 +2054,7 @@ static void cast_slice_to_bool(SemaContext *context, Expr *expr, Type *type) * 1. int[] -> Foo[] where Foo is a distinct or typedef or pointer. Then we can just redefine * 2. The second case is something like int[] -> float[] for this case we need to make a bitcast using CAST_SASA. */ -static void cast_slice_to_slice(SemaContext *context, Expr *expr, Type *to_type) +static void cast_slice_to_slice(Expr *expr, Type *to_type) { if (sema_cast_const(expr)) { @@ -2003,7 +2064,7 @@ static void cast_slice_to_slice(SemaContext *context, Expr *expr, Type *to_type) expr_rewrite_recast(expr, to_type); } -static void cast_vecarr_to_slice(SemaContext *context, Expr *expr, Type *to_type) +static void cast_vecarr_to_slice(Expr *expr, Type *to_type) { if (!sema_cast_const(expr)) { @@ -2037,7 +2098,7 @@ static void cast_vecarr_to_slice(SemaContext *context, Expr *expr, Type *to_type } UNREACHABLE } -static void cast_slice_to_vecarr(SemaContext *context, Expr *expr, Type *to_type) +static void cast_slice_to_vecarr(Expr *expr, Type *to_type) { if (!sema_cast_const(expr)) { @@ -2064,25 +2125,25 @@ static void cast_slice_to_vecarr(SemaContext *context, Expr *expr, Type *to_type return; } -static void cast_slice_to_infer(SemaContext *context, Expr *expr, Type *to_type) +static void cast_slice_to_infer(Expr *expr, Type *to_type) { ArraySize len = sema_len_from_const(expr); ASSERT(len > 0); Type *indexed = type_get_indexed_type(expr->type); to_type = type_infer_len_from_actual_type(to_type, type_get_array(indexed, len)); - cast_no_check(context, expr, to_type, false); + cast_no_check(expr, to_type, false); } -static void cast_vecarr_to_infer(SemaContext *context, Expr *expr, Type *to_type) +static void cast_vecarr_to_infer(Expr *expr, Type *to_type) { to_type = type_infer_len_from_actual_type(to_type, type_flatten(expr->type)); - cast_no_check(context, expr, to_type, false); + cast_no_check(expr, to_type, false); } -static void cast_ptr_to_infer(SemaContext *context, Expr *expr, Type *to_type) +static void cast_ptr_to_infer(Expr *expr, Type *to_type) { to_type = type_infer_len_from_actual_type(to_type, type_flatten(expr->type)); - cast_no_check(context, expr, to_type, false); + cast_no_check(expr, to_type, false); } @@ -2090,7 +2151,7 @@ static void cast_ptr_to_infer(SemaContext *context, Expr *expr, Type *to_type) * Cast using CAST_ARRVEC, casting an array to a vector. For the constant, this * is a simple type change. */ -static void cast_arr_to_vec(SemaContext *context, Expr *expr, Type *to_type) +static void cast_arr_to_vec(Expr *expr, Type *to_type) { Type *index_vec = type_flatten(type_get_indexed_type(to_type)); Type *index_arr = type_flatten(type_get_indexed_type(expr->type)); @@ -2112,22 +2173,22 @@ static void cast_arr_to_vec(SemaContext *context, Expr *expr, Type *to_type) } if (to_temp != to_type) { - cast_vec_to_vec(context, expr, to_type); + cast_vec_to_vec(expr, to_type); } } -static void cast_arr_to_arr(SemaContext *context, Expr *expr, Type *to_type) +static void cast_arr_to_arr(Expr *expr, Type *to_type) { ASSERT(type_size(to_type) == type_size(expr->type)); expr->type = to_type; } -static void cast_anyfault_to_bool(SemaContext *context, Expr *expr, Type *to_type) +static void cast_anyfault_to_bool(Expr *expr, Type *to_type) { expr_rewrite_int_to_bool(expr, false); expr->type = to_type; } -static void cast_typeid_to_bool(SemaContext *context, Expr *expr, Type *to_type) { expr_rewrite_int_to_bool(expr, false); expr->type = to_type; } +static void cast_typeid_to_bool(Expr *expr, Type *to_type) { expr_rewrite_int_to_bool(expr, false); expr->type = to_type; } #define XX2XX &cast_retype #define BS2IA &cast_bitstruct_to_int_arr diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 6498a2e18..19a2afdc8 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -4190,7 +4190,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) if (type_is_user_defined(type) && type->decl) { if (!sema_analyse_decl(context, type->decl)) return false; - sema_display_deprecated_warning_on_use(context, type->decl, type_info->span); + sema_display_deprecated_warning_on_use(type->decl, type_info->span); } if (is_static && context->call_env.pure) diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 3fc7c48cc..863d7b48e 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -91,7 +91,7 @@ static bool sema_expr_analyse_enum_add_sub(SemaContext *context, Expr *expr, Exp static bool sema_expr_analyse_shift(SemaContext *context, Expr *expr, Expr *left, Expr *right); static bool sema_expr_check_shift_rhs(SemaContext *context, Expr *expr, Type *left_type, Type *left_type_flat, Expr *right, Type *right_type_flat); static bool sema_expr_analyse_and_or(SemaContext *context, Expr *expr, Expr *left, Expr *right); -static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped); +static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right); static bool sema_expr_analyse_ct_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right); static bool sema_expr_analyse_ct_type_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right); static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref); @@ -175,7 +175,7 @@ static inline void sema_expr_rewrite_to_type_nameof(Expr *expr, Type *type, Toke static inline bool sema_create_const_kind(SemaContext *contect, Expr *expr, Type *type); static inline bool sema_create_const_len(SemaContext *context, Expr *expr, Type *type); static inline bool sema_create_const_inner(SemaContext *context, Expr *expr, Type *type); -static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type *type, Type *flat); +static inline bool sema_create_const_min(Expr *expr, Type *type, Type *flat); static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type *type, Type *flat); static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type); static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment, AlignSize offset); @@ -912,7 +912,7 @@ static inline bool sema_expr_analyse_ternary(SemaContext *context, Type *infer_t if (expr_is_const(cond)) { Expr *copy = copy_expr_single(cond); - cast_no_check(context, copy, type_bool, false); + cast_no_check(copy, type_bool, false); ASSERT_SPAN(expr, expr_is_const_bool(copy)); path = copy->const_expr.b ? COND_TRUE : COND_FALSE; expr->ternary_expr.then_expr = exprid(cond); @@ -1026,7 +1026,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, ASSERT_SPAN(expr, expr->resolve_status != RESOLVE_DONE); DeclId body_param; - if (!expr->unresolved_ident_expr.path && context->current_macro && (body_param = context->current_macro->func_decl.body_param)) + if (!expr->unresolved_ident_expr.path && context->current_macro && (body_param = context->current_macro->func_decl.body_param)) // NOLINT { if (expr->unresolved_ident_expr.ident == declptr(body_param)->name) { @@ -1086,7 +1086,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, { if (!sema_analyse_decl(context, decl)) return decl_poison(decl); } - sema_display_deprecated_warning_on_use(context, decl, expr->span); + sema_display_deprecated_warning_on_use(decl, expr->span); unit_register_external_symbol(context, decl); if (decl->decl_kind == DECL_VAR) @@ -1780,7 +1780,7 @@ SPLAT_NORMAL:; RETURN_SEMA_ERROR(arg, "A value of type %s cannot be passed as a raw variadic argument.", type_quoted_error_string(arg->type)); } - cast_promote_vararg(context, arg); + cast_promote_vararg(arg); } // Set the argument at the location. *optional |= IS_OPTIONAL(arg); @@ -1946,7 +1946,6 @@ static inline bool sema_call_analyse_func_invocation(SemaContext *context, Decl static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Type *func_ptr_type, bool optional, bool *no_match_ref) { - Decl *decl = NULL; func_ptr_type = type_flat_distinct_inline(func_ptr_type); if (func_ptr_type->type_kind != TYPE_FUNC_PTR) { @@ -2066,7 +2065,7 @@ static inline bool sema_expr_analyse_func_call(SemaContext *context, Expr *expr, return false; } - sema_display_deprecated_warning_on_use(context, decl, expr->span); + sema_display_deprecated_warning_on_use(decl, expr->span); // Tag dynamic dispatch. if (struct_var && decl->func_decl.attr_interface_method) expr->call_expr.is_dynamic_dispatch = true; @@ -2093,7 +2092,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s "possibly due non-terminating macro recursion."); } - sema_display_deprecated_warning_on_use(context, decl, call_expr->span); + sema_display_deprecated_warning_on_use(decl, call_expr->span); copy_begin(); Decl **params = copy_decl_list_macro(decl->func_decl.signature.params); @@ -2414,7 +2413,6 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s Expr *result = ret ? ret->return_stmt.expr : NULL; if (!result) goto NOT_CT; if (!expr_is_runtime_const(result)) goto NOT_CT; - bool only_ct_params = true; FOREACH(Decl *, param, params) { // Skip raw vararg @@ -2532,8 +2530,6 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c call->body_expansion_expr.values = args; call->body_expansion_expr.declarations = macro_context->yield_params; AstId last_defer = context->active_scope.defer_last; - bool success; - bool ends_in_jump; SCOPE_START unsigned ct_context = sema_context_push_ct_stack(context); if (macro_defer) @@ -2579,7 +2575,7 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c } -void sema_expr_convert_enum_to_int(SemaContext *context, Expr *expr) +void sema_expr_convert_enum_to_int(Expr *expr) { ASSERT(type_flatten(expr->type)->type_kind == TYPE_ENUM); Type *underlying_type = type_base(expr->type); @@ -3465,7 +3461,6 @@ INLINE bool sema_expr_analyse_range_internal(SemaContext *context, Range *range, RETURN_SEMA_ERROR(end, "Indexing from the end is not allowed for pointers or flexible array members."); } } - bool end_is_const = !end || sema_cast_const(end); if (end && sema_cast_const(end)) { // Only ArrayIndex sized @@ -3649,7 +3644,6 @@ static inline void sema_slice_initializer(SemaContext *context, Expr *expr, Expr vec_erase_at(initializer->init_array.elements, i); elements--; i--; - continue; } } if (vec_size(initializer->init_array.elements) == 0) @@ -3824,9 +3818,7 @@ RETRY: case EXPR_CT_EVAL: { ASSERT_SPAN(child, child->resolve_status != RESOLVE_DONE); - TokenType type; // Only report missing if missing var is NULL - Path *path = NULL; Expr *result = sema_ct_eval_expr(context, false, child->inner_expr, missing == NULL); if (!result) { @@ -4281,7 +4273,7 @@ static inline bool sema_create_const_parent(SemaContext *context, Expr *expr, Ty return true; } -static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type *type, Type *flat) +static inline bool sema_create_const_min(Expr *expr, Type *type, Type *flat) { if (type_is_float(flat)) { @@ -4313,7 +4305,7 @@ static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type } return true; } - else if (type_is_integer(flat)) + if (type_is_integer(flat)) { expr->expr_kind = EXPR_CONST; expr->const_expr.const_kind = CONST_INTEGER; @@ -4523,7 +4515,7 @@ static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type } return true; } - else if (type_is_float(flat)) + if (type_is_float(flat)) { expr->expr_kind = EXPR_CONST; expr->const_expr.const_kind = CONST_FLOAT; @@ -4874,7 +4866,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, case TYPE_PROPERTY_LEN: return sema_create_const_len(context, expr, flat); case TYPE_PROPERTY_MIN: - return sema_create_const_min(context, expr, type, flat); + return sema_create_const_min(expr, type, flat); case TYPE_PROPERTY_MAX: return sema_create_const_max(context, expr, type, flat); case TYPE_PROPERTY_NAMES: @@ -5119,7 +5111,6 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo } // 3. Find the actual token. - SourceSpan span; Expr *identifier = sema_expr_resolve_access_child(context, child, missing_ref); if (!identifier) return false; const char *kw = identifier->unresolved_ident_expr.ident; @@ -5249,7 +5240,7 @@ CHECK_DEEPER: { if (flat_type->type_kind == TYPE_ENUM) { - sema_expr_convert_enum_to_int(context, current_parent); + sema_expr_convert_enum_to_int(current_parent); expr_replace(expr, current_parent); return true; } @@ -5672,7 +5663,7 @@ static inline bool sema_expr_analyse_cast(SemaContext *context, Expr *expr, bool return true; } -static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped) +static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right) { Expr *left = exprptr(expr->binary_expr.left); if (!sema_analyse_expr(context, right)) return false; @@ -5786,7 +5777,7 @@ bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type { if (expr && exprptr(expr->binary_expr.left)->expr_kind == EXPR_SLICE) { - return sema_expr_analyse_slice_assign(context, expr, left_type, right, is_unwrapped); + return sema_expr_analyse_slice_assign(context, expr, left_type, right); } // 1. Evaluate right side to required type. @@ -6276,12 +6267,12 @@ static void sema_binary_unify_voidptr(SemaContext *context, Expr *left, Expr *ri if (*left_type_ref == *right_type_ref) return; if (*left_type_ref == type_voidptr) { - cast_no_check(context, left, *right_type_ref, IS_OPTIONAL(left)); + cast_no_check(left, *right_type_ref, IS_OPTIONAL(left)); *left_type_ref = *right_type_ref; } if (*right_type_ref == type_voidptr) { - cast_no_check(context, right, *left_type_ref, IS_OPTIONAL(right)); + cast_no_check(right, *left_type_ref, IS_OPTIONAL(right)); *right_type_ref = *left_type_ref; } } @@ -6305,7 +6296,6 @@ static bool sema_expr_analyse_enum_add_sub(SemaContext *context, Expr *expr, Exp { Type *left_type = type_no_optional(left->type)->canonical; bool is_sub = expr->binary_expr.operator == BINARYOP_SUB; - bool swapped = false; if (left_type->type_kind != TYPE_ENUM) { if (is_sub) @@ -6332,8 +6322,8 @@ static bool sema_expr_analyse_enum_add_sub(SemaContext *context, Expr *expr, Exp type_quoted_error_string(right->type)); } Type *underlying_type = left_type->decl->enums.type_info->type; - sema_expr_convert_enum_to_int(context, left); - sema_expr_convert_enum_to_int(context, right); + sema_expr_convert_enum_to_int(left); + sema_expr_convert_enum_to_int(right); expr->type = type_add_optional(underlying_type, IS_OPTIONAL(left) || IS_OPTIONAL(right)); if (expr_both_const(left, right)) { @@ -6354,7 +6344,7 @@ static bool sema_expr_analyse_enum_add_sub(SemaContext *context, Expr *expr, Exp } // Enum - value / Enum + value - sema_expr_convert_enum_to_int(context, left); + sema_expr_convert_enum_to_int(left); if (!cast_implicit(context, right, left->type, true)) return false; expr->type = type_add_optional(left_type, IS_OPTIONAL(left) || IS_OPTIONAL(right)); if (expr_both_const(left, right)) @@ -7078,7 +7068,7 @@ static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left, || (type_is_signed(left_type) && type_is_unsigned(right_type))) { // 2a. Resize so that both sides have the same bit width. This will always work. - cast_to_int_to_max_bit_size(context, left, right, left_type, right_type); + cast_to_int_to_max_bit_size(left, right, left_type, right_type); goto DONE; } @@ -7920,43 +7910,43 @@ INLINE bool expr_is_ungrouped_ternary(Expr *expr) return expr->expr_kind == EXPR_TERNARY && !expr->ternary_expr.grouped; } -static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr, Expr *lhs, Expr *rhs) +static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr, Expr *left, Expr *right) { - bool lhs_is_embed = lhs->expr_kind == EXPR_EMBED; - if (expr_is_ungrouped_ternary(lhs) || expr_is_ungrouped_ternary(rhs)) + bool lhs_is_embed = left->expr_kind == EXPR_EMBED; + if (expr_is_ungrouped_ternary(left) || expr_is_ungrouped_ternary(right)) { SEMA_ERROR(expr, "Unclear precedence using ternary with ??, please use () to remove ambiguity."); return false; } if (lhs_is_embed) { - if (!sema_expr_analyse_embed(context, lhs, true)) return false; + if (!sema_expr_analyse_embed(context, left, true)) return false; } else { - if (!sema_analyse_expr(context, lhs)) return false; + if (!sema_analyse_expr(context, left)) return false; } - Type *type = lhs->type; + Type *type = left->type; if (!type_is_optional(type)) { if (lhs_is_embed) { - expr_replace(expr, lhs); + expr_replace(expr, left); return true; } - RETURN_SEMA_ERROR(lhs, "No optional to use '\?\?' with, please remove the '\?\?'."); + RETURN_SEMA_ERROR(left, "No optional to use '\?\?' with, please remove the '\?\?'."); return false; } bool active_scope_jump = context->active_scope.jump_end; // First we analyse the "else" and try to implictly cast. - if (!sema_analyse_expr(context, rhs)) return false; + if (!sema_analyse_expr(context, right)) return false; - if (lhs->expr_kind == EXPR_OPTIONAL) + if (left->expr_kind == EXPR_OPTIONAL) { - expr_replace(expr, rhs); + expr_replace(expr, right); return true; } @@ -7964,7 +7954,7 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr, context->active_scope.jump_end = active_scope_jump; // Here we might need to insert casts. - Type *else_type = rhs->type; + Type *else_type = right->type; // Remove any possible optional of the else type. @@ -7974,12 +7964,12 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr, Type *common = type_find_max_type(type, else_type); if (!common) { - SEMA_ERROR(rhs, "Cannot find a common type for %s and %s.", type_quoted_error_string(type), + SEMA_ERROR(right, "Cannot find a common type for %s and %s.", type_quoted_error_string(type), type_quoted_error_string(else_type)); return false; } - if (!cast_implicit(context, lhs, common, false)) return false; - if (!cast_implicit(context, rhs, common, false)) return false; + if (!cast_implicit(context, left, common, false)) return false; + if (!cast_implicit(context, right, common, false)) return false; expr->type = type_add_optional(common, add_optional); return true; } @@ -8998,7 +8988,6 @@ static inline Decl *sema_find_cached_lambda(SemaContext *context, Type *func_typ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, bool allow_fail) { - static File no_file; Expr *filename = expr->embed_expr.filename; if (!sema_analyse_ct_expr(context, filename)) return false; Expr *len_expr = expr->embed_expr.len; @@ -9019,8 +9008,6 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo CompilationUnit *unit = context->unit; const char *string = filename->const_expr.bytes.ptr; - bool loaded; - const char *error; char *path; char *name; if (file_namesplit(unit->file->full_path, &name, &path)) @@ -10104,10 +10091,10 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo RETURN_SEMA_ERROR(expr, "Slice length mismatch, expected %u but got %u.", to_canonical->array.len, len); } // Given x[3..7] -> (int[5]*)x[3..7] - cast_no_check(context, expr, type_get_ptr(type_get_array(element, len)), IS_OPTIONAL(expr)); + cast_no_check(expr, type_get_ptr(type_get_array(element, len)), IS_OPTIONAL(expr)); // Deref expr_rewrite_insert_deref(expr); - cast_no_check(context, expr, to, IS_OPTIONAL(expr)); + cast_no_check(expr, to, IS_OPTIONAL(expr)); return true; } NO_SLICE:; @@ -10159,8 +10146,7 @@ static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr, bool mutat case EXPR_MACRO_BODY_EXPANSION: if (!expr->body_expansion_expr.first_stmt) { - SEMA_ERROR(expr, "'@%s' must be followed by ().", declptr(context->current_macro->func_decl.body_param)->name); - return false; + RETURN_SEMA_ERROR(expr, "'@%s' must be followed by ().", declptr(context->current_macro->func_decl.body_param)->name); // NOLINT } break; case EXPR_TYPECALL: diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index e32da9d1b..f8fe2d273 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -203,8 +203,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte if (elements_needed == 0) { // Generate a nice error message for zero. - SEMA_ERROR(elements[0], "Too many elements in initializer, it must be empty."); - return false; + RETURN_SEMA_ERROR(elements[0], "Too many elements in initializer, it must be empty."); } bool optional = false; @@ -780,6 +779,7 @@ ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *expr) { + if (!to) to = type_untypedlist; ASSERT(to); Type *flattened = type_flatten(to); diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 0dd436990..aea14d3f2 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -113,16 +113,16 @@ Expr *sema_create_struct_from_expressions(Decl *struct_decl, SourceSpan span, Ex ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, ConstInitializer *rhs, BinaryOp op); void sema_invert_bitstruct_const_initializer(ConstInitializer *initializer); ArrayIndex sema_len_from_const(Expr *expr); -void cast_promote_vararg(SemaContext *context, Expr *arg); +void cast_promote_vararg(Expr *arg); Type *cast_numeric_arithmetic_promotion(Type *type); -void cast_to_int_to_max_bit_size(SemaContext *context, Expr *lhs, Expr *rhs, Type *left_type, Type *right_type); +void cast_to_int_to_max_bit_size(Expr *lhs, Expr *rhs, Type *left_type, Type *right_type); bool sema_decl_if_cond(SemaContext *context, Decl *decl); Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, const char *name, SourceSpan span, Expr **params, bool *was_recursive_ref); Type *sema_resolve_type_get_func(Signature *signature, CallABI abi); INLINE bool sema_set_abi_alignment(SemaContext *context, Type *type, AlignSize *result); INLINE bool sema_set_alloca_alignment(SemaContext *context, Type *type, AlignSize *result); -INLINE void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *decl, SourceSpan use); +INLINE void sema_display_deprecated_warning_on_use(Decl *decl, SourceSpan use); bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *concat_expr, Expr *left, Expr *right); @@ -154,7 +154,7 @@ INLINE Attr* attr_find_kind(Attr **attrs, AttributeType attr_type) return NULL; } -INLINE void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *decl, SourceSpan span) +INLINE void sema_display_deprecated_warning_on_use(Decl *decl, SourceSpan span) { ASSERT(decl->resolve_status == RESOLVE_DONE); if (!decl->resolved_attributes || !decl->attrs_resolved || !decl->attrs_resolved->deprecated) return; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 60cbabbaf..7143c808c 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -1171,7 +1171,7 @@ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType { RETURN_SEMA_ERROR(last->decl_expr->var.init_expr, "The expression needs to be convertible to a boolean."); } - cast_no_check(context, last, type_bool, false); + cast_no_check(last, type_bool, false); } if (cast_to_bool && expr_is_const_bool(init)) { diff --git a/test/test_suite/compile_time/more_untyped_conversions.c3t b/test/test_suite/compile_time/more_untyped_conversions.c3t new file mode 100644 index 000000000..41c4cf772 --- /dev/null +++ b/test/test_suite/compile_time/more_untyped_conversions.c3t @@ -0,0 +1,47 @@ +// #target: macos-x64 +module test; + +struct Foo { int a; struct { int b; int c; }} +fn int main() +{ + var $z = { { 1, 2 }, { }}; + int[2][] z = $z; + int[2][2] z_slice = $z; + var $c = { 1, { 3, 4 }}; + var $d = { 1, 2 }; + Foo f = $c; + int[?] y = $d; + return 0; +} + +/* #expect: test.ll + +@.__const = private unnamed_addr constant %Foo { i32 1, %.anon { i32 3, i32 4 } }, align 4 +@.__const.2 = private unnamed_addr constant [2 x i32] [i32 1, i32 2], align 4 + +entry: + %z = alloca %"int[2][]", align 8 + %literal = alloca [2 x [2 x i32]], align 16 + %z_slice = alloca [2 x [2 x i32]], align 16 + %f = alloca %Foo, align 4 + %y = alloca [2 x i32], align 4 + store i32 1, ptr %literal, align 4 + %ptradd = getelementptr inbounds i8, ptr %literal, i64 4 + store i32 2, ptr %ptradd, align 4 + %ptradd1 = getelementptr inbounds i8, ptr %literal, i64 8 + store i32 0, ptr %ptradd1, align 4 + %ptradd2 = getelementptr inbounds i8, ptr %ptradd1, i64 4 + store i32 0, ptr %ptradd2, align 4 + %0 = insertvalue %"int[2][]" undef, ptr %literal, 0 + %1 = insertvalue %"int[2][]" %0, i64 2, 1 + store %"int[2][]" %1, ptr %z, align 8 + store i32 1, ptr %z_slice, align 4 + %ptradd3 = getelementptr inbounds i8, ptr %z_slice, i64 4 + store i32 2, ptr %ptradd3, align 4 + %ptradd4 = getelementptr inbounds i8, ptr %z_slice, i64 8 + store i32 0, ptr %ptradd4, align 4 + %ptradd5 = getelementptr inbounds i8, ptr %ptradd4, i64 4 + store i32 0, ptr %ptradd5, align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %f, ptr align 4 @.__const, i32 12, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %y, ptr align 4 @.__const.2, i32 8, i1 false) + ret i32 0 \ No newline at end of file