summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--6/blob.c23
-rw-r--r--parse/fold.c2
-rw-r--r--parse/infer.c32
-rw-r--r--parse/parse.h1
4 files changed, 35 insertions, 23 deletions
diff --git a/6/blob.c b/6/blob.c
index 410acab..c78a6f2 100644
--- a/6/blob.c
+++ b/6/blob.c
@@ -99,17 +99,6 @@ blobfree(Blob *b)
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 @@ static size_t
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 @@ blobslice(Blob *seq, Htab *globls, Htab *strtab, Node *n)
/* 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");
}
diff --git a/parse/fold.c b/parse/fold.c
index c13b41c..da97bb5 100644
--- 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;
diff --git a/parse/infer.c b/parse/infer.c
index e32a16c..cdf1935 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2174,6 +2174,7 @@ tyfix(Node *ctx, Type *orig, int noerr)
static Bitset *intset, *fltset;
Type *t, *d, *base;
Tyenv *env;
+ vlong val;
size_t i;
char buf[1024];
@@ -2193,6 +2194,7 @@ tyfix(Node *ctx, Type *orig, int noerr)
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 @@ tyfix(Node *ctx, Type *orig, int noerr)
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,14 +2239,19 @@ tyfix(Node *ctx, Type *orig, int noerr)
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));
if (base) {
diff --git a/parse/parse.h b/parse/parse.h
index 4e1bbd1..a33af81 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -562,6 +562,7 @@ void addextlibs(char **libs, size_t nlibs);
/* expression folding */
Node *fold(Node *n, int foldvar);
+int getintlit(Node *lit, vlong *val);
/* typechecking/inference */
void infer(void);