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: