From: fennecdjay Date: Sun, 15 Sep 2019 16:19:17 +0000 (+0200) Subject: :bug: [AFL] nonnull fptr X-Git-Tag: nightly~2217 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=25b1f6527edfd3644b1fc2a3d7d7351f6d0d6b32;p=gwion.git :bug: [AFL] nonnull fptr --- diff --git a/include/env.h b/include/env.h index c45805cc..d0a1a1a8 100644 --- a/include/env.h +++ b/include/env.h @@ -53,7 +53,7 @@ ANN Type type_decl_resolve(const Env, const Type_Decl*); ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def); ANN Type known_type(const Env env, const Type_Decl*); -ANN Type known_type_noref(const Env env, const Type_Decl* td); +ANN Type type_nonnull(const Env env, const Type base); ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td); ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos); ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos); diff --git a/src/lib/func.c b/src/lib/func.c index b9f30fbb..6167e2b0 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -187,9 +187,10 @@ ANN static m_bool fptr_lambda(const Env env, struct FptrInfo *info) { ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) { if(isa(info->exp->type, t_lambda) < 0) { + m_bool nonnull = GET_FLAG(info->exp->type, nonnull); CHECK_BB(fptr_check(env, info)) DECL_OB(const Type, t, = fptr_type(env, info)) - info->exp->type = t; + info->exp->type = !nonnull ? t : type_nonnull(env, t); return GW_OK; } return fptr_lambda(env, info); @@ -234,7 +235,8 @@ static OP_EMIT(opem_fptr_cast) { Exp_Cast* cast = (Exp_Cast*)data; if(exp_self(cast)->type->e->d.func->def->base->tmpl) fptr_instr(emit, cast->exp->type->e->d.func, 1); - if(GET_FLAG(cast->exp->type->e->d.func, member)) + if(GET_FLAG(cast->exp->type->e->d.func, member) && + !(GET_FLAG(cast->exp->type, nonnull) || GET_FLAG(exp_self(cast)->type, nonnull))) member_fptr(emit); return GW_OK; } @@ -249,7 +251,8 @@ static OP_CHECK(opck_fptr_impl) { static OP_EMIT(opem_fptr_impl) { struct Implicit *impl = (struct Implicit*)data; - if(GET_FLAG(impl->t->e->d.func, member)) + if(GET_FLAG(impl->t->e->d.func, member) && + !(GET_FLAG(impl->e->type, nonnull) || GET_FLAG(impl->t, nonnull))) member_fptr(emit); if(impl->t->e->d.func->def->base->tmpl) fptr_instr(emit, ((Exp)impl->e)->type->e->d.func, 1); diff --git a/src/oo/nspc.c b/src/oo/nspc.c index c3105d3f..dad4e10c 100644 --- a/src/oo/nspc.c +++ b/src/oo/nspc.c @@ -32,9 +32,11 @@ ANN static void free_nspc_value(const Nspc a, Gwion gwion) { Value v; if(!a->is_union) { while(scope_iter(&iter, &v) > 0) { - if(isa(v->type, t_object) > 0) - nspc_release_object(a, v, gwion); - REM_REF(v, gwion); + if(v) { + if(isa(v->type, t_object) > 0) + nspc_release_object(a, v, gwion); + REM_REF(v, gwion); + } } } free_scope(gwion->mp, a->info->value); diff --git a/src/parse/check.c b/src/parse/check.c index 53232bfa..42b37583 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -485,9 +485,10 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp (func->def->base->tmpl && is_fptr(func->value_ref->type) > 0)) { if(SAFE_FLAG(func->value_ref->owner_class, template)) CHECK_BO(template_push_types(env, func->value_ref->owner_class->e->def->base.tmpl)) - e1->type = known_type(env, e1->td); + e1->type = known_type(env, e1->td); if(SAFE_FLAG(func->value_ref->owner_class, template)) nspc_pop_type(env->gwion->mp, env->curr); + CHECK_OO(e1->type) } if(func_match_inner(env, e, e1->type, implicit, specific) < 0) break; @@ -648,7 +649,7 @@ ANN static void print_current_args(Exp e) { } ANN static void print_arg(Arg_List e) { - do gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type->name, + do gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type ? e->type->name : NULL, e->var_decl->xid ? s_name(e->var_decl->xid) : ""); while((e = e->next) && gw_err(",")); } diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index 245d5db3..d361f317 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -13,6 +13,26 @@ #define STR_NONNULL ":nonnull" #define STRLEN_NONNULL strlen(STR_NONNULL) +#include "func.h" + +ANN Type type_nonnull(const Env env, const Type base) { + char c[strlen(base->name) + 9]; + sprintf(c, "%s%s", base->name, STR_NONNULL); + const Symbol sym = insert_symbol(c); + const Type exist = nspc_lookup_type1(base->e->owner, sym); + if(exist) + return exist; + const Type t = type_copy(env->gwion->mp, base); + t->e->parent = base; + if(t->nspc) + ADD_REF(t->nspc) + t->name = s_name(sym); + t->flag = base->flag; + SET_FLAG(t, nonnull); + map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t); + return t; +} + ANN Type type_decl_resolve(const Env env, const Type_Decl* td) { DECL_OO(const Type, base, = find_type(env, td->xid)) DECL_OO(const Type, t, = scan_type(env, base, td)) @@ -22,21 +42,7 @@ ANN Type type_decl_resolve(const Env env, const Type_Decl* td) { ERR_O(td_pos(td), _("void types can't be nonnull.")) if(isa(ret, t_object) < 0 && isa(ret, t_function) < 0) return ret; - char c[strlen(t->name) + 9]; - sprintf(c, "%s%s", ret->name, STR_NONNULL); - const Symbol sym = insert_symbol(c); - const Type exist = nspc_lookup_type1(t->e->owner, sym); - if(exist) - return exist; - const Type t = type_copy(env->gwion->mp, ret); - t->e->parent = ret; - if(t->nspc) - ADD_REF(t->nspc) - t->name = s_name(sym); - t->flag = ret->flag; - SET_FLAG(t, nonnull); - map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t); - return t; + return type_nonnull(env, ret); } return ret; }