shithub: mc

Download patch

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);
 }