shithub: mc

Download patch

ref: aeff53ae83c1b00f86934d85033d710f8826ba36
parent: b17873ed4e6a14786758fd68290ef572b0b88f10
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Oct 15 17:59:43 EDT 2018

Disallow negative array sizes. And do some cleanup.

--- a/6/blob.c
+++ b/6/blob.c
@@ -99,17 +99,6 @@
 	free(b);
 }
 
-static size_t
-getintlit(Node *n, char *failmsg)
-{
-	if (exprop(n) != Olit)
-		fatal(n, "%s", failmsg);
-	n = n->expr.args[0];
-	if (n->lit.littype != Lint)
-		fatal(n, "%s", failmsg);
-	return n->lit.intval;
-}
-
 void
 b(Blob *b, Blob *n)
 {
@@ -188,7 +177,7 @@
 blobslice(Blob *seq,  Htab *globls, Htab *strtab, Node *n)
 {
 	Node *base, *lo, *hi;
-	ssize_t loval, hival, sz;
+	vlong loval, hival, baseval, sz;
 	Blob *slbase;
 	char *lbl;
 
@@ -199,14 +188,18 @@
 	/* by this point, all slicing operations should have had their base
 	 * pulled out, and we should have vars with their pseudo-decls in their
 	 * place */
-	loval = getintlit(lo, "lower bound in slice is not constant literal");
-	hival = getintlit(hi, "upper bound in slice is not constant literal");
+	if (!getintlit(lo, &loval))
+		fatal(lo, "lower bound in slice is not constant literal");
+	if (!getintlit(hi, &hival))
+		fatal(hi, "upper bound in slice is not constant literal");
 	if (exprop(base) == Ovar && base->expr.isconst) {
 		sz = tysize(tybase(exprtype(base))->sub[0]);
 		lbl = htget(globls, base);
 		slbase = mkblobref(lbl, loval*sz, 1);
 	} else if (exprop(base) == Olit || exprop(base) == Oarr) {
-		slbase = mkblobi(Bti64, getintlit(base, "invalid base expr"));
+		if (!getintlit(base, &baseval))
+			fatal(base, "invalid base expr");
+		slbase = mkblobi(Bti64, baseval);
 	} else {
 		fatal(base, "slice base is not a constant value");
 	}
--- a/parse/fold.c
+++ b/parse/fold.c
@@ -15,7 +15,7 @@
 
 size_t (*sizefn)(Node *n);
 
-static int
+int
 getintlit(Node *n, vlong *v)
 {
 	Node *l;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2174,6 +2174,7 @@
 	static Bitset *intset, *fltset;
 	Type *t, *d, *base;
 	Tyenv *env;
+	vlong val;
 	size_t i;
 	char buf[1024];
 
@@ -2193,6 +2194,7 @@
 	if (env)
 		pushenv(env);
 	base = orig->seqaux;
+	/* Process delayed type mappings. */
 	if (orig->type == Tyvar && hthas(delayed, orig)) {
 		d = htget(delayed, orig);
 		if (t->type == Tyvar) {
@@ -2204,21 +2206,32 @@
 			    tystr(t), tystr(d), ctxstr(ctx));
 		}
 	}
+
+	/* Default the type */
 	if (t->type == Tyvar && t->trneed) {
 		if (bsissubset(t->trneed, intset))
 			t = tyint;
 		else if (bsissubset(t->trneed, fltset))
 			t = tyflt;
-	} else if (!t->fixed) {
+	}
+
+	if (!t->fixed) {
 		t->fixed = 1;
-		if (t->type == Tyarray) {
+		switch(t->type) {
+		case Tyarray:
+			if (t->type == Tyarray && t->asize)
+				t->asize = fold(t->asize, 1);
+			if (getintlit(t->asize, &val) && val < 0)
+				fatal(t->asize, "negative array size %lld\n", val);
 			typesub(t->asize, noerr);
-		} else if (t->type == Tystruct) {
+			break;
+		case Tystruct:
 			inaggr++;
 			for (i = 0; i < t->nmemb; i++)
 				typesub(t->sdecls[i], noerr);
 			inaggr--;
-		} else if (t->type == Tyunion) {
+			break;
+		case Tyunion:
 			for (i = 0; i < t->nmemb; i++) {
 				if (t->udecls[i]->etype) {
 					tyresolve(t->udecls[i]->etype);
@@ -2226,13 +2239,18 @@
 						tyfix(ctx, t->udecls[i]->etype, noerr);
 				}
 			}
-		} else if (t->type == Tyname) {
+			break;
+		case Tyname:
 			for (i = 0; i < t->narg; i++)
 				t->arg[i] = tyfix(ctx, t->arg[i], noerr);
+			break;
+		default:
+			break;
 		}
-		for (i = 0; i < t->nsub; i++)
-			t->sub[i] = tyfix(ctx, t->sub[i], noerr);
 	}
+
+	for (i = 0; i < t->nsub; i++)
+		t->sub[i] = tyfix(ctx, t->sub[i], noerr);
 
 	if (t->type == Tyvar && !noerr)
 		fatal(ctx, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(ctx));
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -562,6 +562,7 @@
 
 /* expression folding */
 Node *fold(Node *n, int foldvar);
+int getintlit(Node *lit, vlong *val);
 
 /* typechecking/inference */
 void infer(void);