diff options
Diffstat (limited to 'src/cmd/gc/walk.c')
-rw-r--r-- | src/cmd/gc/walk.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 53040fe93..9bd0a699c 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -432,6 +432,10 @@ walkexpr(Node **np, NodeList **init) walkexpr(&n->left, init); goto ret; + case OITAB: + walkexpr(&n->left, init); + goto ret; + case OLEN: case OCAP: walkexpr(&n->left, init); @@ -1051,6 +1055,8 @@ walkexpr(Node **np, NodeList **init) walkexpr(&r, nil); } typecheck(&r, Erv); + if(n->type->etype != TBOOL) fatal("cmp %T", n->type); + r->type = n->type; n = r; goto ret; @@ -1176,10 +1182,17 @@ walkexpr(Node **np, NodeList **init) argtype(fn, n->right->type); argtype(fn, n->left->type); r = mkcall1(fn, n->type, init, n->left, n->right); - if(n->etype == ONE) { + if(n->etype == ONE) r = nod(ONOT, r, N); - typecheck(&r, Erv); - } + + // check itable/type before full compare. + if(n->etype == OEQ) + r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); + else + r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); + typecheck(&r, Erv); + walkexpr(&r, nil); + r->type = n->type; n = r; goto ret; @@ -1203,10 +1216,11 @@ walkexpr(Node **np, NodeList **init) fatal("missing switch %O", n->op); ret: + ullmancalc(n); + if(debug['w'] && n != N) dump("walk", n); - ullmancalc(n); lineno = lno; *np = n; } |