summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2019-01-08 23:31:15 -0800
committerOri Bernstein <ori@eigenstate.org>2019-01-12 00:03:23 -0800
commit63f4ce6387dea9f943ecc9c9f9b7af147560839d (patch)
tree601d3a5edcb21cf34b0ec7ce0396cfe779a37a6d
parente24656bb54b092b936c28ba5c5147d2e91fd0169 (diff)
downloadmc-63f4ce6387dea9f943ecc9c9f9b7af147560839d.tar.gz
Fix indexed array initializers.
-rw-r--r--6/blob.c25
-rw-r--r--6/simp.c20
2 files changed, 41 insertions, 4 deletions
diff --git a/6/blob.c b/6/blob.c
index c78a6f2..ffa2e1e 100644
--- a/6/blob.c
+++ b/6/blob.c
@@ -286,6 +286,8 @@ static size_t
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 @@ blobrec(Blob *b, Htab *globls, Htab *strtab, Node *n)
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)
@@ -308,6 +309,28 @@ blobrec(Blob *b, Htab *globls, Htab *strtab, Node *n)
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));
+ sz += blobpad(b, end - sz);
+ break;
default:
dump(n, stdout);
die("Nonliteral initializer for global");
diff --git a/6/simp.c b/6/simp.c
index 8bb0d88..415f49d 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -1124,6 +1124,7 @@ rval(Simp *s, Node *n, Node *dst)
Node *t, *u, *v; /* temporary nodes */
Node *r; /* expression result */
Node **args;
+ vlong idx, nelt;
size_t i;
Type *ty;
@@ -1165,9 +1166,22 @@ rval(Simp *s, Node *n, Node *dst)
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 @@ rval(Simp *s, Node *n, Node *dst)
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: