mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 20:58:15 +00:00
Add sanity conversion check for integer to quaternion
This commit is contained in:
+23
-21
@@ -2929,6 +2929,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
|
|||||||
void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
|
void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
gb_mutex_lock(&c->info->untyped_mutex);
|
gb_mutex_lock(&c->info->untyped_mutex);
|
||||||
|
defer (gb_mutex_unlock(&c->info->untyped_mutex));
|
||||||
ExprInfo *old = check_get_expr_info(c->info, e);
|
ExprInfo *old = check_get_expr_info(c->info, e);
|
||||||
if (old == nullptr) {
|
if (old == nullptr) {
|
||||||
if (type != nullptr && type != t_invalid) {
|
if (type != nullptr && type != t_invalid) {
|
||||||
@@ -2939,26 +2940,6 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!final && is_type_untyped(type)) {
|
|
||||||
old->type = base_type(type);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// We need to remove it and then give it a new one
|
|
||||||
map_remove(&c->info->untyped, hash_node(e));
|
|
||||||
|
|
||||||
if (old->is_lhs && !is_type_integer(type)) {
|
|
||||||
gbString expr_str = expr_to_string(e);
|
|
||||||
gbString type_str = type_to_string(type);
|
|
||||||
error(e, "Shifted operand %s must be an integer, got %s", expr_str, type_str);
|
|
||||||
gb_string_free(type_str);
|
|
||||||
gb_string_free(expr_str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_type_and_value(c->info, e, old->mode, type, old->value);
|
|
||||||
}
|
|
||||||
gb_mutex_unlock(&c->info->untyped_mutex);
|
|
||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case_ast_node(ue, UnaryExpr, e);
|
case_ast_node(ue, UnaryExpr, e);
|
||||||
if (old->value.kind != ExactValue_Invalid) {
|
if (old->value.kind != ExactValue_Invalid) {
|
||||||
@@ -3009,6 +2990,25 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
|
|||||||
update_expr_type(c, pe->expr, type, final);
|
update_expr_type(c, pe->expr, type, final);
|
||||||
case_end;
|
case_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!final && is_type_untyped(type)) {
|
||||||
|
old->type = base_type(type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to remove it and then give it a new one
|
||||||
|
map_remove(&c->info->untyped, hash_node(e));
|
||||||
|
|
||||||
|
if (old->is_lhs && !is_type_integer(type)) {
|
||||||
|
gbString expr_str = expr_to_string(e);
|
||||||
|
gbString type_str = type_to_string(type);
|
||||||
|
error(e, "Shifted operand %s must be an integer, got %s", expr_str, type_str);
|
||||||
|
gb_string_free(type_str);
|
||||||
|
gb_string_free(expr_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_type_and_value(c->info, e, old->mode, type, old->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_expr_value(CheckerContext *c, Ast *e, ExactValue value) {
|
void update_expr_value(CheckerContext *c, Ast *e, ExactValue value) {
|
||||||
@@ -3247,7 +3247,9 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
|
|||||||
if (i > 0 && count > 2) error_line(", ");
|
if (i > 0 && count > 2) error_line(", ");
|
||||||
if (i == count-1) {
|
if (i == count-1) {
|
||||||
if (count == 2) error_line(" ");
|
if (count == 2) error_line(" ");
|
||||||
error_line("or ");
|
if (count > 1) {
|
||||||
|
error_line("or ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gbString str = type_to_string(v);
|
gbString str = type_to_string(v);
|
||||||
error_line("'%s'", str);
|
error_line("'%s'", str);
|
||||||
|
|||||||
@@ -8106,6 +8106,14 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
|||||||
return lb_addr_load(p, gen);
|
return lb_addr_load(p, gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_type_integer(src) && is_type_complex(dst)) {
|
||||||
|
Type *ft = base_complex_elem_type(dst);
|
||||||
|
lbAddr gen = lb_add_local_generated(p, dst, true);
|
||||||
|
lbValue gp = lb_addr_get_ptr(p, gen);
|
||||||
|
lbValue real = lb_emit_conv(p, value, ft);
|
||||||
|
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
|
||||||
|
return lb_addr_load(p, gen);
|
||||||
|
}
|
||||||
if (is_type_float(src) && is_type_complex(dst)) {
|
if (is_type_float(src) && is_type_complex(dst)) {
|
||||||
Type *ft = base_complex_elem_type(dst);
|
Type *ft = base_complex_elem_type(dst);
|
||||||
lbAddr gen = lb_add_local_generated(p, dst, true);
|
lbAddr gen = lb_add_local_generated(p, dst, true);
|
||||||
@@ -8114,6 +8122,17 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
|||||||
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
|
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
|
||||||
return lb_addr_load(p, gen);
|
return lb_addr_load(p, gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (is_type_integer(src) && is_type_quaternion(dst)) {
|
||||||
|
Type *ft = base_complex_elem_type(dst);
|
||||||
|
lbAddr gen = lb_add_local_generated(p, dst, true);
|
||||||
|
lbValue gp = lb_addr_get_ptr(p, gen);
|
||||||
|
lbValue real = lb_emit_conv(p, value, ft);
|
||||||
|
// @QuaternionLayout
|
||||||
|
lb_emit_store(p, lb_emit_struct_ep(p, gp, 3), real);
|
||||||
|
return lb_addr_load(p, gen);
|
||||||
|
}
|
||||||
if (is_type_float(src) && is_type_quaternion(dst)) {
|
if (is_type_float(src) && is_type_quaternion(dst)) {
|
||||||
Type *ft = base_complex_elem_type(dst);
|
Type *ft = base_complex_elem_type(dst);
|
||||||
lbAddr gen = lb_add_local_generated(p, dst, true);
|
lbAddr gen = lb_add_local_generated(p, dst, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user