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:
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;