mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
CHECK 1 done
Fix panic in LLVM backend when using generic procedure with default arguments - Fixed panic in `llvm_backend_proc.cpp` when using unspecialized polymorphic procedures as defaults. - Ensured correct type inference when generic procedures are used as default parameters.
This commit is contained in:
@@ -533,7 +533,10 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
|
|||||||
Entity *e = entity_from_expr(expr);
|
Entity *e = entity_from_expr(expr);
|
||||||
res = lb_find_procedure_value_from_entity(m, e);
|
res = lb_find_procedure_value_from_entity(m, e);
|
||||||
}
|
}
|
||||||
GB_ASSERT(res.value != nullptr);
|
if (res.value == nullptr) {
|
||||||
|
// This is an unspecialized polymorphic procedure, return nil or dummy value
|
||||||
|
return lb_const_nil(m, original_type);
|
||||||
|
}
|
||||||
GB_ASSERT(LLVMGetValueKind(res.value) == LLVMFunctionValueKind);
|
GB_ASSERT(LLVMGetValueKind(res.value) == LLVMFunctionValueKind);
|
||||||
|
|
||||||
if (LLVMGetIntrinsicID(res.value) == 0) {
|
if (LLVMGetIntrinsicID(res.value) == 0) {
|
||||||
|
|||||||
@@ -885,8 +885,8 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|||||||
Type *t = base_type(type_deref(addr.addr.type));
|
Type *t = base_type(type_deref(addr.addr.type));
|
||||||
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
||||||
lbValue len = lb_soa_struct_len(p, addr.addr);
|
lbValue len = lb_soa_struct_len(p, addr.addr);
|
||||||
if (addr.soa.index_expr != nullptr) {
|
if (addr.soa.index_expr != nullptr && (!lb_is_const(addr.soa.index) || t->Struct.soa_kind != StructSoa_Fixed)) {
|
||||||
lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), index, len);
|
lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), addr.soa.index, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2728,6 +2728,14 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e)
|
|||||||
ignore_body = other_module != m;
|
ignore_body = other_module != m;
|
||||||
|
|
||||||
lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
|
lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
|
||||||
|
if (missing_proc == nullptr) {
|
||||||
|
// This is an unspecialized polymorphic procedure, which should not be codegen'd
|
||||||
|
lbValue dummy = {};
|
||||||
|
dummy.value = nullptr;
|
||||||
|
dummy.type = nullptr;
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
if (ignore_body) {
|
if (ignore_body) {
|
||||||
mutex_lock(&gen->anonymous_proc_lits_mutex);
|
mutex_lock(&gen->anonymous_proc_lits_mutex);
|
||||||
defer (mutex_unlock(&gen->anonymous_proc_lits_mutex));
|
defer (mutex_unlock(&gen->anonymous_proc_lits_mutex));
|
||||||
|
|||||||
@@ -67,6 +67,14 @@ gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValu
|
|||||||
gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
|
gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
|
||||||
GB_ASSERT(entity != nullptr);
|
GB_ASSERT(entity != nullptr);
|
||||||
GB_ASSERT(entity->kind == Entity_Procedure);
|
GB_ASSERT(entity->kind == Entity_Procedure);
|
||||||
|
// Skip codegen for unspecialized polymorphic procedures
|
||||||
|
if (is_type_polymorphic(entity->type) && !entity->Procedure.is_foreign) {
|
||||||
|
Type *bt = base_type(entity->type);
|
||||||
|
if (bt->kind == Type_Proc && bt->Proc.is_polymorphic && !bt->Proc.is_poly_specialized) {
|
||||||
|
// Do not generate code for unspecialized polymorphic procedures
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!entity->Procedure.is_foreign) {
|
if (!entity->Procedure.is_foreign) {
|
||||||
if ((entity->flags & EntityFlag_ProcBodyChecked) == 0) {
|
if ((entity->flags & EntityFlag_ProcBodyChecked) == 0) {
|
||||||
GB_PANIC("%.*s :: %s (was parapoly: %d %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true), is_type_polymorphic(entity->type, false));
|
GB_PANIC("%.*s :: %s (was parapoly: %d %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true), is_type_polymorphic(entity->type, false));
|
||||||
@@ -815,6 +823,10 @@ gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e)
|
|||||||
e->Procedure.link_name = name;
|
e->Procedure.link_name = name;
|
||||||
|
|
||||||
lbProcedure *nested_proc = lb_create_procedure(p->module, e);
|
lbProcedure *nested_proc = lb_create_procedure(p->module, e);
|
||||||
|
if (nested_proc == nullptr) {
|
||||||
|
// This is an unspecialized polymorphic procedure, skip codegen
|
||||||
|
return;
|
||||||
|
}
|
||||||
e->code_gen_procedure = nested_proc;
|
e->code_gen_procedure = nested_proc;
|
||||||
|
|
||||||
lbValue value = {};
|
lbValue value = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user