mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-08 16:48:18 +00:00
Correct union type checking for constants
This commit is contained in:
+66
-60
@@ -821,11 +821,13 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
|
||||
}
|
||||
}
|
||||
|
||||
if (c != nullptr) {
|
||||
if (is_type_enum(dst) && are_types_identical(dst->Enum.base_type, operand->type)) {
|
||||
if (c->in_enum_type) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
@@ -3590,12 +3592,8 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forb
|
||||
Type *final_type = type;
|
||||
if (is_const_expr && !is_type_constant_type(type)) {
|
||||
if (is_type_union(type)) {
|
||||
if (is_type_union_constantable(type)) {
|
||||
|
||||
} else {
|
||||
convert_to_typed(c, x, type);
|
||||
}
|
||||
}
|
||||
final_type = default_type(x->type);
|
||||
}
|
||||
update_untyped_expr_type(c, x->expr, final_type, true);
|
||||
@@ -8033,62 +8031,8 @@ gb_internal bool check_call_parameter_mixture(Slice<Ast *> const &args, char con
|
||||
return Expr_Stmt; \
|
||||
}
|
||||
|
||||
|
||||
gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice<Ast *> const &args, ProcInlining inlining, Type *type_hint) {
|
||||
if (proc != nullptr &&
|
||||
proc->kind == Ast_BasicDirective) {
|
||||
ast_node(bd, BasicDirective, proc);
|
||||
String name = bd->name.string;
|
||||
if (
|
||||
name == "location" ||
|
||||
name == "exists" ||
|
||||
name == "assert" ||
|
||||
name == "panic" ||
|
||||
name == "defined" ||
|
||||
name == "config" ||
|
||||
name == "load" ||
|
||||
name == "load_directory" ||
|
||||
name == "load_hash" ||
|
||||
name == "hash" ||
|
||||
name == "caller_expression"
|
||||
) {
|
||||
operand->mode = Addressing_Builtin;
|
||||
operand->builtin_id = BuiltinProc_DIRECTIVE;
|
||||
operand->expr = proc;
|
||||
operand->type = t_invalid;
|
||||
add_type_and_value(c, proc, operand->mode, operand->type, operand->value);
|
||||
} else {
|
||||
error(proc, "Unknown directive: #%.*s", LIT(name));
|
||||
operand->expr = proc;
|
||||
operand->type = t_invalid;
|
||||
operand->mode = Addressing_Invalid;
|
||||
return Expr_Expr;
|
||||
}
|
||||
if (inlining != ProcInlining_none) {
|
||||
error(call, "Inlining operators are not allowed on built-in procedures");
|
||||
}
|
||||
} else {
|
||||
if (proc != nullptr) {
|
||||
check_expr_or_type(c, operand, proc);
|
||||
} else {
|
||||
GB_ASSERT(operand->expr != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
|
||||
for (Ast *arg : args) {
|
||||
if (arg->kind == Ast_FieldValue) {
|
||||
arg = arg->FieldValue.value;
|
||||
}
|
||||
check_expr_base(c, operand, arg, nullptr);
|
||||
}
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = call;
|
||||
return Expr_Stmt;
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Type) {
|
||||
gb_internal ExprKind check_call_expr_as_type_cast(CheckerContext *c, Operand *operand, Ast *call, Slice<Ast *> const &args, Type *type_hint) {
|
||||
GB_ASSERT(operand->mode == Addressing_Type);
|
||||
Type *t = operand->type;
|
||||
if (is_type_polymorphic_record(t)) {
|
||||
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("polymorphic type construction");
|
||||
@@ -8174,6 +8118,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
}
|
||||
operand->type = t;
|
||||
operand->expr = call;
|
||||
|
||||
|
||||
if (operand->mode != Addressing_Invalid) {
|
||||
update_untyped_expr_type(c, arg, t, false);
|
||||
}
|
||||
@@ -8184,6 +8130,66 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
return Expr_Expr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice<Ast *> const &args, ProcInlining inlining, Type *type_hint) {
|
||||
if (proc != nullptr &&
|
||||
proc->kind == Ast_BasicDirective) {
|
||||
ast_node(bd, BasicDirective, proc);
|
||||
String name = bd->name.string;
|
||||
if (
|
||||
name == "location" ||
|
||||
name == "exists" ||
|
||||
name == "assert" ||
|
||||
name == "panic" ||
|
||||
name == "defined" ||
|
||||
name == "config" ||
|
||||
name == "load" ||
|
||||
name == "load_directory" ||
|
||||
name == "load_hash" ||
|
||||
name == "hash" ||
|
||||
name == "caller_expression"
|
||||
) {
|
||||
operand->mode = Addressing_Builtin;
|
||||
operand->builtin_id = BuiltinProc_DIRECTIVE;
|
||||
operand->expr = proc;
|
||||
operand->type = t_invalid;
|
||||
add_type_and_value(c, proc, operand->mode, operand->type, operand->value);
|
||||
} else {
|
||||
error(proc, "Unknown directive: #%.*s", LIT(name));
|
||||
operand->expr = proc;
|
||||
operand->type = t_invalid;
|
||||
operand->mode = Addressing_Invalid;
|
||||
return Expr_Expr;
|
||||
}
|
||||
if (inlining != ProcInlining_none) {
|
||||
error(call, "Inlining operators are not allowed on built-in procedures");
|
||||
}
|
||||
} else {
|
||||
if (proc != nullptr) {
|
||||
check_expr_or_type(c, operand, proc);
|
||||
} else {
|
||||
GB_ASSERT(operand->expr != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
|
||||
for (Ast *arg : args) {
|
||||
if (arg->kind == Ast_FieldValue) {
|
||||
arg = arg->FieldValue.value;
|
||||
}
|
||||
check_expr_base(c, operand, arg, nullptr);
|
||||
}
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = call;
|
||||
return Expr_Stmt;
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Type) {
|
||||
return check_call_expr_as_type_cast(c, operand, call, args, type_hint);
|
||||
}
|
||||
|
||||
if (operand->mode == Addressing_Builtin) {
|
||||
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("builtin call");
|
||||
|
||||
|
||||
@@ -3256,7 +3256,7 @@ gb_internal lbAddr lb_add_global_generated_with_name(lbModule *m, Type *type, lb
|
||||
LLVMTypeRef actual_type = lb_type(m, type);
|
||||
if (value.value != nullptr) {
|
||||
LLVMTypeRef value_type = LLVMTypeOf(value.value);
|
||||
GB_ASSERT(lb_sizeof(actual_type) == lb_sizeof(value_type));
|
||||
GB_ASSERT_MSG(lb_sizeof(actual_type) == lb_sizeof(value_type), "%s vs %s", LLVMPrintTypeToString(actual_type), LLVMPrintTypeToString(value_type));
|
||||
actual_type = value_type;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user