mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 20:58:15 +00:00
Extra check for type_info cycle checking
This commit is contained in:
+26
-9
@@ -3242,23 +3242,40 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case BuiltinProc_type_of:
|
case BuiltinProc_type_of: {
|
||||||
// proc type_of(val: Type) -> type(Type)
|
// proc type_of(val: Type) -> type(Type)
|
||||||
check_assignment(c, operand, nullptr, str_lit("argument of 'type_of'"));
|
AstNode *expr = ce->args[0];
|
||||||
if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) {
|
Operand o = {};
|
||||||
|
check_expr_or_type(c, &o, expr);
|
||||||
|
|
||||||
|
// check_assignment(c, operand, nullptr, str_lit("argument of 'type_of'"));
|
||||||
|
if (o.mode == Addressing_Invalid || o.mode == Addressing_Builtin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (operand->type == nullptr || operand->type == t_invalid) {
|
if (o.type == nullptr || o.type == t_invalid) {
|
||||||
error(operand->expr, "Invalid argument to 'type_of'");
|
error(o.expr, "Invalid argument to 'type_of'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_type_polymorphic(operand->type)) {
|
if (o.type == nullptr || o.type == t_invalid) {
|
||||||
error(operand->expr, "'type_of' of polymorphic type cannot be determined");
|
error(o.expr, "Invalid argument to 'type_of'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// NOTE(bill): Prevent type cycles for procedure declarations
|
||||||
|
if (c->context.curr_proc_sig == o.type) {
|
||||||
|
gbString s = expr_to_string(o.expr);
|
||||||
|
error(o.expr, "Invalid cyclic type usage from 'type_of', got '%s'", s);
|
||||||
|
gb_string_free(s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_type_polymorphic(o.type)) {
|
||||||
|
error(o.expr, "'type_of' of polymorphic type cannot be determined");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
operand->mode = Addressing_Type;
|
operand->mode = Addressing_Type;
|
||||||
|
operand->type = o.type;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case BuiltinProc_type_info_of: {
|
case BuiltinProc_type_info_of: {
|
||||||
// proc type_info_of(Type) -> ^Type_Info
|
// proc type_info_of(Type) -> ^Type_Info
|
||||||
@@ -3270,7 +3287,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
init_preload(c);
|
init_preload(c);
|
||||||
AstNode *expr = ce->args[0];
|
AstNode *expr = ce->args[0];
|
||||||
Operand o = {};
|
Operand o = {};
|
||||||
check_expr_or_type(c, &o, ce->args[0]);
|
check_expr_or_type(c, &o, expr);
|
||||||
if (o.mode == Addressing_Invalid) {
|
if (o.mode == Addressing_Invalid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1671,6 +1671,10 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
|
|||||||
c->context.polymorphic_scope = c->context.scope;
|
c->context.polymorphic_scope = c->context.scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckerContext prev = c->context;
|
||||||
|
defer (c->context = prev);
|
||||||
|
c->context.curr_proc_sig = type;
|
||||||
|
|
||||||
bool variadic = false;
|
bool variadic = false;
|
||||||
isize variadic_index = -1;
|
isize variadic_index = -1;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ struct CheckerContext {
|
|||||||
String proc_name;
|
String proc_name;
|
||||||
Type * type_hint;
|
Type * type_hint;
|
||||||
DeclInfo * curr_proc_decl;
|
DeclInfo * curr_proc_decl;
|
||||||
|
Type * curr_proc_sig;
|
||||||
ForeignContext foreign_context;
|
ForeignContext foreign_context;
|
||||||
|
|
||||||
bool collect_delayed_decls;
|
bool collect_delayed_decls;
|
||||||
|
|||||||
Reference in New Issue
Block a user