]> Cypherpunks.ru repositories - gostls13.git/commitdiff
gc: new, less strict bool rules
authorRuss Cox <rsc@golang.org>
Wed, 22 Feb 2012 05:29:37 +0000 (00:29 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 22 Feb 2012 05:29:37 +0000 (00:29 -0500)
R=ken2
CC=golang-dev
https://golang.org/cl/5688064

src/cmd/gc/const.c
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
test/named1.go

index 15c760b3a6c2d589e74465653db35b35d42f344d..e27c88338741b8d6e4da3493cfdda31c0b414fb5 100644 (file)
@@ -87,6 +87,8 @@ convlit1(Node **np, Type *t, int explicit)
 
        switch(n->op) {
        default:
+               if(n->type == idealbool)
+                       n->type = types[TBOOL];
                if(n->type->etype == TIDEAL) {
                        convlit(&n->left, t);
                        convlit(&n->right, t);
@@ -1010,6 +1012,10 @@ defaultlit(Node **np, Type *t)
                }
                n->type = t;
                return;
+       case ONOT:
+               defaultlit(&n->left, t);
+               n->type = n->left->type;
+               return;
        default:
                if(n->left == N) {
                        dump("defaultlit", n);
@@ -1029,13 +1035,18 @@ defaultlit(Node **np, Type *t)
                } else if(t == T && (n->left->op == OLSH || n->left->op == ORSH)) {
                        defaultlit(&n->right, T);
                        defaultlit(&n->left, n->right->type);
+               } else if(iscmp[n->op]) {
+                       defaultlit2(&n->left, &n->right, 1);
                } else {
                        defaultlit(&n->left, t);
                        defaultlit(&n->right, t);
                }
-               if(n->type == idealbool || n->type == idealstring)
-                       n->type = types[n->type->etype];
-               else
+               if(n->type == idealbool || n->type == idealstring) {
+                       if(t != T && t->etype == n->type->etype)
+                               n->type = t;
+                       else
+                               n->type = types[n->type->etype];
+               } else
                        n->type = n->left->type;
                return;
        }
@@ -1124,6 +1135,10 @@ defaultlit2(Node **lp, Node **rp, int force)
        }
        if(!force)
                return;
+       if(l->type->etype == TBOOL) {
+               convlit(lp, types[TBOOL]);
+               convlit(rp, types[TBOOL]);
+       }
        if(isconst(l, CTCPLX) || isconst(r, CTCPLX)) {
                convlit(lp, types[TCOMPLEX128]);
                convlit(rp, types[TCOMPLEX128]);
index 5621ed9d343fa62040dc4dc1babf805ef980dee2..12ac6fcb97f0175b1e7b0e630c67a29032344a0b 100644 (file)
@@ -1354,6 +1354,18 @@ assignconv(Node *n, Type *t, char *context)
        if(t->etype == TBLANK)
                return n;
 
+       // Convert ideal bool from comparison to plain bool
+       // if the next step is non-bool (like interface{}).
+       if(n->type == idealbool && t->etype != TBOOL) {
+               if(n->op == ONAME || n->op == OLITERAL) {
+                       r = nod(OCONVNOP, n, N);
+                       r->type = types[TBOOL];
+                       r->typecheck = 1;
+                       r->implicit = 1;
+                       n = r;
+               }
+       }
+
        if(eqtype(n->type, t))
                return n;
 
index 5bb386d8e508cea00c805b4cc8e04c6fb9a7d83a..90bd24964e1707e8c5a70ebc5cd82a2d6a000fbd 100644 (file)
@@ -526,7 +526,7 @@ reswitch:
                t = l->type;
                if(iscmp[n->op]) {
                        evconst(n);
-                       t = types[TBOOL];
+                       t = idealbool;
                        if(n->op != OLITERAL) {
                                defaultlit2(&l, &r, 1);
                                n->left = l;
@@ -1317,6 +1317,13 @@ reswitch:
        case OPRINTN:
                ok |= Etop;
                typechecklist(n->list, Erv | Eindir);  // Eindir: address does not escape
+               for(args=n->list; args; args=args->next) {
+                       // Special case for print: int constant is int64, not int.
+                       if(isconst(args->n, CTINT))
+                               defaultlit(&args->n, types[TINT64]);
+                       else
+                               defaultlit(&args->n, T);
+               }
                goto ret;
 
        case OPANIC:
@@ -2887,6 +2894,8 @@ typecheckdef(Node *n)
        }
 
 ret:
+       if(n->op != OLITERAL && n->type != T && isideal(n->type))
+               fatal("got %T for %N", n->type, n);
        if(typecheckdefstack->n != n)
                fatal("typecheckdefstack mismatch");
        l = typecheckdefstack;
index ea18766e30463cabfd83e62982d3fdb01ef86d78..9bd0a699cb72a4256dd2bf41868715a6208abe59 100644 (file)
@@ -1055,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;
 
@@ -1190,7 +1192,7 @@ walkexpr(Node **np, NodeList **init)
                        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;
 
index ca9da0fa31a1cb4b41563b68fcd97e21b3b75f1c..5ff6930f7d0757dddbd8b950924ded50a0242667 100644 (file)
@@ -37,8 +37,8 @@ func main() {
        asBool(true)
        asBool(*&b)
        asBool(Bool(true))
-       asBool(1 != 2) // ERROR "cannot use.*type bool.*as type Bool"
-       asBool(i < j)  // ERROR "cannot use.*type bool.*as type Bool"
+       asBool(1 != 2) // ok now
+       asBool(i < j)  // ok now
 
        _, b = m[2] // ERROR "cannot .* bool.*type Bool"