mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Disallow anonymous structs with procedures as default values
This commit is contained in:
@@ -3301,6 +3301,11 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
check_struct_type(c, *type, e, nullptr, named_type);
|
check_struct_type(c, *type, e, nullptr, named_type);
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
(*type)->Struct.node = e;
|
(*type)->Struct.node = e;
|
||||||
|
|
||||||
|
if (named_type == nullptr && (*type)->Struct.has_proc_default_values) {
|
||||||
|
error(e, "Anonymous structs cannot have procedures as default values");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|||||||
+54
-18
@@ -3754,6 +3754,39 @@ irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, AstNode *exp
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ir_check_type_and_gen_for_proc_lit(irProcedure *proc, Type *t) {
|
||||||
|
if (t == nullptr) return;
|
||||||
|
if (t->kind == Type_Struct && t->Struct.has_proc_default_values) {
|
||||||
|
for_array(i, t->Struct.fields) {
|
||||||
|
Entity *f = t->Struct.fields[i];
|
||||||
|
if (f->kind == Entity_Variable && f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
if (expr->kind == AstNode_ProcLit) {
|
||||||
|
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ir_check_type_and_gen_for_proc_lit(irModule *m, String prefix_name, Type *t) {
|
||||||
|
if (t == nullptr) return;
|
||||||
|
if (t->kind == Type_Struct && t->Struct.has_proc_default_values) {
|
||||||
|
for_array(i, t->Struct.fields) {
|
||||||
|
Entity *f = t->Struct.fields[i];
|
||||||
|
if (f->kind == Entity_Variable && f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
if (expr->kind == AstNode_ProcLit) {
|
||||||
|
ir_gen_anonymous_proc_lit(m, prefix_name, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
||||||
if (e->type == nullptr) return;
|
if (e->type == nullptr) return;
|
||||||
|
|
||||||
@@ -3805,22 +3838,7 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (bt->kind == Type_Struct) {
|
ir_check_type_and_gen_for_proc_lit(m, e->token.string, bt);
|
||||||
if (bt->Struct.has_proc_default_values) {
|
|
||||||
for_array(i, bt->Struct.fields) {
|
|
||||||
Entity *f = bt->Struct.fields[i];
|
|
||||||
if (f->kind == Entity_Variable) {
|
|
||||||
if (f->Variable.default_value.kind == ExactValue_Procedure) {
|
|
||||||
AstNode *expr = f->Variable.default_value.value_procedure;
|
|
||||||
GB_ASSERT(expr != nullptr);
|
|
||||||
if (expr->kind == AstNode_ProcLit) {
|
|
||||||
ir_gen_anonymous_proc_lit(m, e->token.string, expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6389,8 +6407,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
ir_add_local_for_identifier(proc, name, false);
|
ir_add_local_for_identifier(proc, name, false);
|
||||||
lval = ir_build_addr(proc, name);
|
lval = ir_build_addr(proc, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
array_add(&lvals, lval);
|
array_add(&lvals, lval);
|
||||||
|
|
||||||
|
ir_check_type_and_gen_for_proc_lit(proc, ir_addr_type(lval));
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, vd->values) {
|
for_array(i, vd->values) {
|
||||||
@@ -7428,12 +7447,16 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
|
|||||||
auto *p = &proc->type->Proc;
|
auto *p = &proc->type->Proc;
|
||||||
for_array(i, p->params->Tuple.variables) {
|
for_array(i, p->params->Tuple.variables) {
|
||||||
Entity *f = p->params->Tuple.variables[i];
|
Entity *f = p->params->Tuple.variables[i];
|
||||||
if (f->kind == Entity_Variable && f->Variable.default_value.kind == ExactValue_Procedure) {
|
if (f->kind == Entity_Variable) {
|
||||||
|
if (f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
AstNode *expr = f->Variable.default_value.value_procedure;
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
GB_ASSERT(expr != nullptr);
|
GB_ASSERT(expr != nullptr);
|
||||||
if (expr->kind == AstNode_ProcLit) {
|
if (expr->kind == AstNode_ProcLit) {
|
||||||
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ir_check_type_and_gen_for_proc_lit(proc, f->type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7781,6 +7804,19 @@ void ir_gen_tree(irGen *s) {
|
|||||||
var.var = g;
|
var.var = g;
|
||||||
var.decl = decl;
|
var.decl = decl;
|
||||||
|
|
||||||
|
if (e->type->kind == Type_Struct && e->type->Struct.has_proc_default_values) {
|
||||||
|
for_array(i, e->type->Struct.fields) {
|
||||||
|
Entity *f = e->type->Struct.fields[i];
|
||||||
|
if (f->kind == Entity_Variable && f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
if (expr->kind == AstNode_ProcLit) {
|
||||||
|
ir_gen_anonymous_proc_lit(m, e->token.string, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (decl->init_expr != nullptr) {
|
if (decl->init_expr != nullptr) {
|
||||||
if (is_type_any(e->type)) {
|
if (is_type_any(e->type)) {
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user