From aa10c9d0fa568cc9fcdc056999c3cde11d13400b Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 19 Nov 2022 15:00:09 +0100 Subject: [PATCH] :art: Ctor checking --- src/lib/object_op.c | 8 +++---- src/parse/check.c | 51 ++++++++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 8ddf68bf..b2a5c758 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -140,6 +140,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) { } } else if (is_static_call(emit->gwion, exp_self(member))) { if (member->is_call && f == emit->env->func && !is_new(f->def)) return; + if(!member->is_call) emit_regmove(emit, SZ_INT); return emit_pushfunc(emit, f); } else { if (tflag(member->base->type, tflag_struct)) @@ -210,8 +211,8 @@ OP_CHECK(opck_object_dot) { if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class) > 0)) // is_callable needs type return v->type; if (is_class(env->gwion, v->type)) { - DECL_OO(const Type, parent, = class_type(env, member, v->type)); - if (isa(the_base, parent) > 0 && parent->nspc) { + DECL_OO(const Type, parent, = class_type(env, member, v->type)); + if (the_base->info->parent == parent && parent->nspc) { const Symbol sym = insert_symbol(env->gwion->st, "new"); if(!env->func || env->func->def->base->xid != sym) ERR_N(exp_self(member)->pos, "calling a parent constructor is only allowed in `new` definition"); @@ -228,8 +229,7 @@ OP_CHECK(opck_object_dot) { if(ret) return ret->type; } } - } else if(is_class(env->gwion, v->type) && the_base == v->type->info->base_type) - return v->type->info->base_type; + } } env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"), the_base->name, str); diff --git a/src/parse/check.c b/src/parse/check.c index ee4afd8f..82e43087 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1782,6 +1782,31 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef, return GW_OK; } +ANN static bool effect_find(const MP_Vector *v, const Symbol sym) { + for(m_uint i = 0; i < v->len; i++) { + struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); + if(eff->sym == sym) return true; + } + return false; +} + +ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) { + MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects); + if (v) { + if (fdef->base->xid == insert_symbol("@dtor")) + ERR_B(fdef->base->pos, _("can't use effects in destructors")); + const Vector base = &fdef->base->effects; + if (!base->ptr) vector_init(base); + for (uint32_t i = 0; i < v->len; i++) { + struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); + if(!effect_find(v, eff->sym)) + vector_add(base, (m_uint)eff->sym); + } + free_mp_vector(env->gwion->mp, struct ScopeEffect, v); + } + return GW_OK; +} + ANN m_bool check_fdef(const Env env, const Func_Def fdef) { if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args)); if(fdef->builtin) return GW_OK; @@ -1791,17 +1816,16 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) { const m_bool ret = check_stmt_list(env, fdef->d.code); nspc_pop_value(env->gwion->mp, env->curr); env->scope->depth--; + CHECK_BB(check_fdef_effects(env, fdef)); return ret; } return GW_OK; } -ANN static bool effect_find(const MP_Vector *v, const Symbol sym) { - for(m_uint i = 0; i < v->len; i++) { - struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); - if(eff->sym == sym) return true; - } - return false; +ANN static m_bool check_ctor(const Env env, const Func func) { + if(!GET_FLAG(func, const) && nspc_lookup_value0(env->class_def->info->parent->nspc, insert_symbol("new")) && !GET_FLAG(func, const)) + ERR_B(func->def->base->pos, "missing call to parent constructor"); + return GW_OK; } ANN m_bool _check_func_def(const Env env, const Func_Def f) { @@ -1838,19 +1862,6 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) { } vector_add(&env->scope->effects, 0); const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef); - MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects); - if (v) { - if (fdef->base->xid == insert_symbol("@dtor")) - ERR_B(fdef->base->pos, _("can't use effects in destructors")); - const Vector base = &fdef->base->effects; - if (!base->ptr) vector_init(base); - for (uint32_t i = 0; i < v->len; i++) { - struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i); - if(!effect_find(v, eff->sym)) - vector_add(base, (m_uint)eff->sym); - } - free_mp_vector(env->gwion->mp, struct ScopeEffect, v); - } vector_pop(&env->scope->effects); if (fbflag(fdef->base, fbflag_op)) operator_resume(&opi); nspc_pop_value(env->gwion->mp, env->curr); @@ -1861,6 +1872,8 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) { !check_effect_overload(&fdef->base->effects, override->d.func_ref))) ERR_B(fdef->base->pos, _("too much effects in override."), s_name(fdef->base->xid)) + if(is_new(f) && !tflag(env->class_def, tflag_struct)) + CHECK_BB(check_ctor(env, func)); } if (GET_FLAG(fdef->base, global)) env_pop(env, scope); if (func->value_ref->from->owner_class) -- 2.43.0