diff options
author | Ori Bernstein <ori@eigenstate.org> | 2016-08-13 16:38:10 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2016-08-13 16:38:10 -0700 |
commit | ab42f5c4f29b1860d26c40bd05bb123a3ef49a6f (patch) | |
tree | 931f63987f9ae45b0cbabc61562407e0ae7f9fcd /mi | |
parent | 1db8622646327359d06877fb85534a33cfa5ad6b (diff) | |
download | mc-ab42f5c4f29b1860d26c40bd05bb123a3ef49a6f.tar.gz |
Don't generate loops in trees.
We only want to append to last if we're actaully expanding
the match frontier. It's a bug to add it if it's unused.
Diffstat (limited to 'mi')
-rw-r--r-- | mi/match.c | 10 |
1 files changed, 7 insertions, 3 deletions
@@ -297,6 +297,8 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree * for (j = 0; j < nlast; j++) if (addwildrec(loc, ty->sub[i], last[j], next, &tail, &ntail)) ret = 1; + if (i == ty->nsub - 1) + break; lfree(&last, &nlast); last = tail; nlast = ntail; @@ -313,6 +315,8 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree * for (j = 0; j < nlast; j++) if (addwildrec(loc, ty->sub[0], last[j], next, &tail, &ntail)) ret = 1; + if (i == nelt - 1) + break; lfree(&last, &nlast); last = tail; nlast = ntail; @@ -327,13 +331,14 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree * for (j = 0; j < nlast; j++) if (addwildrec(loc, decltype(ty->sdecls[i]), last[j], next, &tail, &ntail)) ret = 1; + if (i == ty->nsub - 1) + break; lfree(&last, &nlast); last = tail; nlast = ntail; } break; case Tyunion: - lappend(&last, &nlast, start); for (i = 0; i < ty->nmemb; i++) { uc = ty->udecls[i]; next = dtbytag(start, uc); @@ -350,14 +355,13 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree * start->any = accept; ret = 1; } - lappend(end, nend, start->any); + lappend(&last, &nlast, accept); break; case Tyslice: ret = acceptall(start, accept); lappend(&last, &nlast, accept); break; case Typtr: - lappend(&last, &nlast, start); ret = addwildrec(loc, ty->sub[0], start, accept, &last, &nlast); break; default: |