shithub: scc

Download patch

ref: 3183b71d83817fd0ad0566889a941b69844e8451
parent: ead5f758ec8bf1a9e0a2d80e34d09f8d78b47526
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 12 08:47:58 EDT 2015

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.

--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -118,14 +118,12 @@
 	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 @@
 
 		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 @@
 			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 @@
 	/*
 	 * 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,6 +663,7 @@
 			sym->flags &= ~ISEMITTED;
 			curfun = sym;
 			emit(OFUN, sym);
+			free(sym->u.pars);
 			compound(NULL, NULL, NULL);
 			emit(OEFUN, NULL);
 			curfun = NULL;
@@ -661,6 +670,7 @@
 			return;
 		default:
 		remove_pars:
+			free(sym->u.pars);
 			popctx();
 		}
 	}
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -130,7 +130,7 @@
 				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;