ref: 80ec974fe1549bf956f40002a7254b5875f978b1
parent: bf24b946be8f54d58030fe143453b269175b3461
author: Ori Bernstein <[email protected]>
date: Sun Jan 24 18:48:10 EST 2016
Only walk pointer patterns that walk pointers.
--- a/mi/match.c
+++ b/mi/match.c
@@ -21,8 +21,9 @@
Node *lbl;
Node *load;
size_t nconstructors;
- int accept;
- int emitted;
+ char accept;
+ char emitted;
+ char ptrwalk;
/* the decision tree step */
Node **pat;
@@ -244,6 +245,13 @@
return ret;
}
+static int isbasictype(Dtree *dt, Type *ty)
+{
+ if (ty->type == Typtr)
+ return !dt->ptrwalk;
+ return istyprimitive(ty) || ty->type == Tyvoid;
+}
+
static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree ***end, size_t *nend)
{
Dtree *next, **last, **tail;
@@ -255,7 +263,7 @@
tail = NULL;
ntail = 0;
ty = tybase(ty);
- if (istyprimitive(ty) || ty->type == Tyvoid) {
+ if (isbasictype(start, ty)) {
if (start->accept || start == accept)
return 0;
for (i = 0; i < start->nnext; i++)
@@ -340,15 +348,7 @@
lappend(&last, &nlast, accept);
break;
case Typtr:
- /* we only want to descend if there's something to match here. */
- if (start->any || start->nnext > 0) {
- ret = addwildrec(loc, ty->sub[0], start, accept, &last, &nlast);
- } else if (!start->any) {
- start->any = accept;
- lappend(end, nend, accept);
- return 1;
- }
- break;
+ ret = addwildrec(loc, ty->sub[0], start, accept, &last, &nlast);
default:
ret = 1;
lappend(&last, &nlast, accept);
@@ -601,6 +601,7 @@
deref = mkexpr(val->loc, Oderef, val, NULL);
deref->expr.type = exprtype(pat->expr.args[0]);
start->nconstructors = nconstructors(exprtype(deref));
+ start->ptrwalk = 1;
return addpat(pat->expr.args[0], deref, start, accept, cap, ncap, end, nend);
}