From 9460f9f14dd68eb59d36f758272be936300a0440 Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 7 Aug 2022 17:57:22 +0200 Subject: fix template accessing future environment --- bootstrap/parse.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'bootstrap/parse.c') diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 7b2e007..99560d8 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -539,20 +539,22 @@ popenv(struct parser *P) { static struct decl * putdecl(struct parser *P, struct span espan, const struct decl *decl) { struct decl *ret; - if (envfind(P->primenv, decl->name)) + if (envfind(P->primenv, INT_MAX, decl->name)) fatal(P, espan, "cannot shadow primitive `%s'", decl->name); if (!(ret = envput(P->curenv, decl))) fatal(P, decl->span, "cannot shadow earlier incompatible declaration of `%s'", decl->name); + if (!P->save_envage) + P->envage = MAX(P->envage, ret->age); return ret; } static const struct decl * finddecl(struct parser *P, const char *name) { const struct decl *decl; - if ((decl = envfind(P->primenv, name))) + if ((decl = envfind(P->primenv, INT_MAX, name))) return decl; - return envfind(P->curenv, name); + return envfind(P->curenv, P->envage, name); } static struct expr parseexpr(struct parser *P); @@ -684,6 +686,7 @@ parseexpandtepl(struct parser *P, struct tepl *tepl) { } struct env env = { tepl->env }; + WITH_TMPCHANGE(struct env *, P->curenv, &env) { struct decl *decl; expan.args.d = args; @@ -691,8 +694,11 @@ parseexpandtepl(struct parser *P, struct tepl *tepl) { expan.toks = tepl->toks; ++P->expanno; P->curexpan = memcpy(xmalloc(sizeof expan), &expan, sizeof expan); - ty = parseagg(P, tepl->name, tepl->tkind, &decl); + WITH_TMPCHANGE(int, P->envage, tepl->envage) + WITH_TMPCHANGE(int, P->save_envage, 1) + ty = parseagg(P, tepl->name, tepl->tkind, &decl); } + free(env.decls); memcpy(&((struct type *)ty)->agg.tpargs, &tpargs, sizeof tpargs); cache = xcalloc(sizeof *cache, 1); cache->next = tepl->cache; @@ -2443,7 +2449,7 @@ parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl) { int iid; struct env env_noparent = *P->curenv; env_noparent.parent = NULL; - struct decl *decl = (struct decl *)envfind(&env_noparent, name); + struct decl *decl = (struct decl *)envfind(&env_noparent, P->envage, name); if (decl && decl->ty->t == kind) iid = decl->ty->agg.id; else @@ -2586,6 +2592,7 @@ parseaggtepl(struct parser *P, int kind, const char *name) { } tepl.env = P->curenv; + tepl.envage = P->envage; vec_slice_cpy(&tepl.params, ¶ms); vec_slice_cpy(&tepl.toks, &toks); return tepl; @@ -2705,6 +2712,8 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) { decl.t = Dtype; decl.ty = parseagg(P, decl.name, kind, &decl2); } else { + if (!toplevel) + fatal(P, tok.span, "template definition inside function"); decl.t = Dtepl; decl.tepl = parseaggtepl(P, kind, decl.name); } -- cgit v1.2.3