Refactor casts and make untyped list conversions not dependent on context.

This commit is contained in:
Christoffer Lerno
2025-02-01 23:37:32 +01:00
parent dc6d994480
commit f8b2f7f268
8 changed files with 263 additions and 169 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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))
{

View File

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