shithub: mc

Download patch

ref: 63f4ce6387dea9f943ecc9c9f9b7af147560839d
parent: e24656bb54b092b936c28ba5c5147d2e91fd0169
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jan 8 18:31:15 EST 2019

Fix indexed array initializers.

--- a/6/blob.c
+++ b/6/blob.c
@@ -286,6 +286,8 @@
 blobrec(Blob *b, Htab *globls, Htab *strtab, Node *n)
 {
 	size_t i, sz, end;
+	vlong nelt, idx, last;
+	Type *ty;
 
 	switch(exprop(n)) {
 	case Oucon:	sz = blobucon(b, globls, strtab, n);	break;
@@ -294,7 +296,6 @@
 	case Ovar:	sz = blobvar(b, strtab, n, exprtype(n));	break;
 	case Olit:	sz = bloblit(b, strtab, n->expr.args[0], exprtype(n));	break;
 	case Otup:
-	case Oarr:
 		/* Assumption: We sorted this while folding */
 		sz = 0;
 		if (!n->expr.args)
@@ -303,6 +304,28 @@
 			end = alignto(sz, exprtype(n->expr.args[i]));
 			sz += blobpad(b, end - sz);
 			sz += blobrec(b, globls, strtab, n->expr.args[i]);
+		}
+		/* if we need padding at the end.. */
+		end = alignto(sz, exprtype(n));
+		sz += blobpad(b, end - sz);
+		break;
+	case Oarr:
+		sz = 0;
+		idx = 0;
+		last = 0;
+		ty = exprtype(n);
+		if (!n->expr.args)
+			break;
+		if (!getintlit(ty->asize, &nelt))
+			die("array missing size");
+		/* We sorted this while folding, so elements are in order */
+		for (i = 0; i < n->expr.nargs; i++) {
+			if (!getintlit(n->expr.args[i]->expr.idx, &idx))
+				die("non-numeric array size");
+			if (idx != last + 1)
+				sz += blobpad(b, (idx - last)*size(n->expr.args[i]));
+			sz += blobrec(b, globls, strtab, n->expr.args[i]);
+			last = idx + 1;
 		}
 		/* if we need padding at the end.. */
 		end = alignto(sz, exprtype(n));
--- a/6/simp.c
+++ b/6/simp.c
@@ -1124,6 +1124,7 @@
 	Node *t, *u, *v; /* temporary nodes */
 	Node *r; /* expression result */
 	Node **args;
+	vlong idx, nelt;
 	size_t i;
 	Type *ty;
 
@@ -1165,9 +1166,22 @@
 	case Oarr:
 		if (!dst)
 			dst = temp(s, n);
+		ty = exprtype(dst);
 		t = addr(s, dst, exprtype(dst));
-		for (i = 0; i < n->expr.nargs; i++)
-			assignat(s, t, size(n->expr.args[i])*i, rval(s, n->expr.args[i], NULL));
+		if (!getintlit(ty->asize, &nelt))
+			die("array missing size");
+		/* we only need to clear if we don't have things fully initialized */
+		idx = 0;
+		if (nelt != n->expr.nargs)
+			append(s, mkexpr(n->loc, Oclear, t, mkintlit(n->loc, size(n)), NULL));
+		for (i = 0; i < n->expr.nargs; i++) {
+			if (!args[i]->expr.idx)
+				idx++;
+			else if (!getintlit(args[i]->expr.idx, &idx))
+				die("non-numeric array size");
+			assert(idx < nelt);
+			assignat(s, t, size(args[i])*idx, rval(s, args[i], NULL));
+		}
 		r = dst;
 		break;
 	case Ostruct:
@@ -1182,7 +1196,7 @@
 		if (tybase(ty)->nmemb != n->expr.nargs)
 			append(s, mkexpr(n->loc, Oclear, t, mkintlit(n->loc, size(n)), NULL));
 		for (i = 0; i < n->expr.nargs; i++)
-			assignat(s, t, offset(n, n->expr.args[i]->expr.idx), rval(s, n->expr.args[i], NULL));
+			assignat(s, t, offset(n, args[i]->expr.idx), rval(s, args[i], NULL));
 		r = dst;
 		break;
 	case Ocast: