diff options
-rw-r--r-- | 6/blob.c | 23 | ||||
-rw-r--r-- | parse/fold.c | 2 | ||||
-rw-r--r-- | parse/infer.c | 32 | ||||
-rw-r--r-- | parse/parse.h | 1 |
4 files changed, 35 insertions, 23 deletions
@@ -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); |