diff options
author | Pavel Machek <pavel@ucw.cz> | 2000-03-02 22:23:18 +0000 |
---|---|---|
committer | Pavel Machek <pavel@ucw.cz> | 2000-03-02 22:23:18 +0000 |
commit | d4d7562806b7306d6e5ed9b759906e264b743dc5 (patch) | |
tree | b33cbd1a31553cedb7cb8adc88543a7a7c383ccc /filter/filter.c | |
parent | c8518ae136d94dc9576531a311947ba13213aea0 (diff) |
Avoid being exponential, do not allow ! =
Diffstat (limited to 'filter/filter.c')
-rw-r--r-- | filter/filter.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/filter/filter.c b/filter/filter.c index f0de20d7..7e526640 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -446,14 +446,16 @@ interpret(struct f_inst *what) int i_same(struct f_inst *f1, struct f_inst *f2) { - if (!f1) - return 1; if ((!!f1) != (!!f2)) return 0; + if (!f1) + return 1; if (f1->aux != f2->aux) return 0; if (f1->code != f2->code) return 0; + if (f1 == f2) /* It looks strange, but it is possible with call rewriting trickery */ + return 1; switch(f1->code) { case ',': /* fall through */ @@ -495,8 +497,12 @@ i_same(struct f_inst *f1, struct f_inst *f2) case 'r': ONEARG; break; case P('c','p'): ONEARG; break; - case P('c','a'): /* CALL, FIXME: exponential in some cases */ - ONEARG; if (!i_same(f1->a2.p, f2->a2.p)) return 0; break; + case P('c','a'): /* Call rewriting trickery to avoid exponential behaviour */ + ONEARG; + if (!i_same(f1->a2.p, f2->a2.p)) + return 0; + f2->a2.p = f1->a2.p; + break; case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break; case P('i','M'): TWOARGS; break; default: |