Commit e29d3dfc authored by Russ Cox's avatar Russ Cox

gc: new, less strict bool rules

R=ken2
CC=golang-dev
https://golang.org/cl/5688064
parent 6c7daca2
...@@ -87,6 +87,8 @@ convlit1(Node **np, Type *t, int explicit) ...@@ -87,6 +87,8 @@ convlit1(Node **np, Type *t, int explicit)
switch(n->op) { switch(n->op) {
default: default:
if(n->type == idealbool)
n->type = types[TBOOL];
if(n->type->etype == TIDEAL) { if(n->type->etype == TIDEAL) {
convlit(&n->left, t); convlit(&n->left, t);
convlit(&n->right, t); convlit(&n->right, t);
...@@ -1010,6 +1012,10 @@ defaultlit(Node **np, Type *t) ...@@ -1010,6 +1012,10 @@ defaultlit(Node **np, Type *t)
} }
n->type = t; n->type = t;
return; return;
case ONOT:
defaultlit(&n->left, t);
n->type = n->left->type;
return;
default: default:
if(n->left == N) { if(n->left == N) {
dump("defaultlit", n); dump("defaultlit", n);
...@@ -1029,13 +1035,18 @@ defaultlit(Node **np, Type *t) ...@@ -1029,13 +1035,18 @@ defaultlit(Node **np, Type *t)
} else if(t == T && (n->left->op == OLSH || n->left->op == ORSH)) { } else if(t == T && (n->left->op == OLSH || n->left->op == ORSH)) {
defaultlit(&n->right, T); defaultlit(&n->right, T);
defaultlit(&n->left, n->right->type); defaultlit(&n->left, n->right->type);
} else if(iscmp[n->op]) {
defaultlit2(&n->left, &n->right, 1);
} else { } else {
defaultlit(&n->left, t); defaultlit(&n->left, t);
defaultlit(&n->right, t); defaultlit(&n->right, t);
} }
if(n->type == idealbool || n->type == idealstring) if(n->type == idealbool || n->type == idealstring) {
n->type = types[n->type->etype]; if(t != T && t->etype == n->type->etype)
else n->type = t;
else
n->type = types[n->type->etype];
} else
n->type = n->left->type; n->type = n->left->type;
return; return;
} }
...@@ -1124,6 +1135,10 @@ defaultlit2(Node **lp, Node **rp, int force) ...@@ -1124,6 +1135,10 @@ defaultlit2(Node **lp, Node **rp, int force)
} }
if(!force) if(!force)
return; return;
if(l->type->etype == TBOOL) {
convlit(lp, types[TBOOL]);
convlit(rp, types[TBOOL]);
}
if(isconst(l, CTCPLX) || isconst(r, CTCPLX)) { if(isconst(l, CTCPLX) || isconst(r, CTCPLX)) {
convlit(lp, types[TCOMPLEX128]); convlit(lp, types[TCOMPLEX128]);
convlit(rp, types[TCOMPLEX128]); convlit(rp, types[TCOMPLEX128]);
......
...@@ -1354,6 +1354,18 @@ assignconv(Node *n, Type *t, char *context) ...@@ -1354,6 +1354,18 @@ assignconv(Node *n, Type *t, char *context)
if(t->etype == TBLANK) if(t->etype == TBLANK)
return n; 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)) if(eqtype(n->type, t))
return n; return n;
......
...@@ -526,7 +526,7 @@ reswitch: ...@@ -526,7 +526,7 @@ reswitch:
t = l->type; t = l->type;
if(iscmp[n->op]) { if(iscmp[n->op]) {
evconst(n); evconst(n);
t = types[TBOOL]; t = idealbool;
if(n->op != OLITERAL) { if(n->op != OLITERAL) {
defaultlit2(&l, &r, 1); defaultlit2(&l, &r, 1);
n->left = l; n->left = l;
...@@ -1317,6 +1317,13 @@ reswitch: ...@@ -1317,6 +1317,13 @@ reswitch:
case OPRINTN: case OPRINTN:
ok |= Etop; ok |= Etop;
typechecklist(n->list, Erv | Eindir); // Eindir: address does not escape 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; goto ret;
case OPANIC: case OPANIC:
...@@ -2887,6 +2894,8 @@ typecheckdef(Node *n) ...@@ -2887,6 +2894,8 @@ typecheckdef(Node *n)
} }
ret: ret:
if(n->op != OLITERAL && n->type != T && isideal(n->type))
fatal("got %T for %N", n->type, n);
if(typecheckdefstack->n != n) if(typecheckdefstack->n != n)
fatal("typecheckdefstack mismatch"); fatal("typecheckdefstack mismatch");
l = typecheckdefstack; l = typecheckdefstack;
......
...@@ -1055,6 +1055,8 @@ walkexpr(Node **np, NodeList **init) ...@@ -1055,6 +1055,8 @@ walkexpr(Node **np, NodeList **init)
walkexpr(&r, nil); walkexpr(&r, nil);
} }
typecheck(&r, Erv); typecheck(&r, Erv);
if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
r->type = n->type;
n = r; n = r;
goto ret; goto ret;
...@@ -1190,7 +1192,7 @@ walkexpr(Node **np, NodeList **init) ...@@ -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); r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
typecheck(&r, Erv); typecheck(&r, Erv);
walkexpr(&r, nil); walkexpr(&r, nil);
r->type = n->type;
n = r; n = r;
goto ret; goto ret;
......
...@@ -37,8 +37,8 @@ func main() { ...@@ -37,8 +37,8 @@ func main() {
asBool(true) asBool(true)
asBool(*&b) asBool(*&b)
asBool(Bool(true)) asBool(Bool(true))
asBool(1 != 2) // ERROR "cannot use.*type bool.*as type Bool" asBool(1 != 2) // ok now
asBool(i < j) // ERROR "cannot use.*type bool.*as type Bool" asBool(i < j) // ok now
_, b = m[2] // ERROR "cannot .* bool.*type Bool" _, b = m[2] // ERROR "cannot .* bool.*type Bool"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment