scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 3183b71d83817fd0ad0566889a941b69844e8451
parent ead5f758ec8bf1a9e0a2d80e34d09f8d78b47526
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 12 Aug 2015 12:47:58 +0200

Free parameter symbols after applying a type operator

After applying a type operator in not possible to use these
parameters anymore, so it is a good place for discarding them.

Diffstat:
Mcc1/decl.c | 26++++++++++++++++++--------
Mcc1/symbol.c | 2+-
2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -118,14 +118,12 @@ fundcl(struct dcldata *dp) Type type = {.n = {.elem = -1}, .pars = NULL}; Symbol *syms[NR_FUNPARAM], **sp; size_t size; - void *p; + void *pars = NULL; pushctx(); expect('('); - if (accept(')')) { - dp = queue(dp, FTN, type.n.elem, type.pars); - } else { + if (!accept(')')) { type.n.elem = 0; sp = syms; do @@ -134,13 +132,13 @@ fundcl(struct dcldata *dp) expect(')'); - dp = queue(dp, FTN, type.n.elem, type.pars); if (type.n.elem != -1) { size = type.n.elem * sizeof(Symbol *); - p = memcpy(xmalloc(size), syms, size); - dp = queue(dp, PARS, 0, p); + pars = memcpy(xmalloc(size), syms, size); } } + dp = queue(dp, PARS, 0, pars); + dp = queue(dp, FTN, type.n.elem, type.pars); return dp; } @@ -210,6 +208,15 @@ declarator(Type *tp, unsigned ns, Type **otp) pars = bp->data; break; default: + if (pars) { + /* + * constructor applied to a function. We don't + * need the parameter symbols anymore. + */ + free(pars); + popctx(); + pars = NULL; + } tp = mktype(tp, bp->op, bp->nelem, bp->data); break; } @@ -217,7 +224,8 @@ declarator(Type *tp, unsigned ns, Type **otp) /* * FIXME: This assignation can destroy pars of a previous definition */ - sym->u.pars = pars; + if (pars) + sym->u.pars = pars; *otp = tp; return sym; } @@ -655,12 +663,14 @@ decl(void) sym->flags &= ~ISEMITTED; curfun = sym; emit(OFUN, sym); + free(sym->u.pars); compound(NULL, NULL, NULL); emit(OEFUN, NULL); curfun = NULL; return; default: remove_pars: + free(sym->u.pars); popctx(); } } diff --git a/cc1/symbol.c b/cc1/symbol.c @@ -130,7 +130,7 @@ popctx(void) warn("'%s' defined but not used", sym->name); } free(sym->name); - // TODO: Fix this memory leak free(sym->u.pars); + // TODO: There is a memory leak with sym->u.s free(sym); } head = sym;