summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-10-15 21:59:43 -0700
committerOri Bernstein <ori@eigenstate.org>2018-10-15 21:59:43 -0700
commitaeff53ae83c1b00f86934d85033d710f8826ba36 (patch)
tree6f089d885f68c596970e227101d25606b6d8990f /parse
parentb17873ed4e6a14786758fd68290ef572b0b88f10 (diff)
downloadmc-aeff53ae83c1b00f86934d85033d710f8826ba36.tar.gz
Disallow negative array sizes. And do some cleanup.
Diffstat (limited to 'parse')
-rw-r--r--parse/fold.c2
-rw-r--r--parse/infer.c32
-rw-r--r--parse/parse.h1
3 files changed, 27 insertions, 8 deletions
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);