Commit 14b0af42 authored by Rémy Oudompheng's avatar Rémy Oudompheng

cmd/gc: fix walkcompare bugs.

Revision c0e0467635ec (cmd/gc: return canonical Node* from temp)
exposed original nodes of temporaries, allowing callers to mutate
their types.

In walkcompare a temporary could be typed as ideal because of
this. Additionnally, assignment of a comparison result to
a custom boolean type was broken.

Fixes #7366.

LGTM=rsc
R=rsc, iant, khr
CC=golang-codereviews
https://golang.org/cl/66930044
parent ff15e5c0
...@@ -3171,13 +3171,10 @@ walkcompare(Node **np, NodeList **init) ...@@ -3171,13 +3171,10 @@ walkcompare(Node **np, NodeList **init)
} }
if(expr == N) if(expr == N)
expr = nodbool(n->op == OEQ); expr = nodbool(n->op == OEQ);
typecheck(&expr, Erv); r = expr;
walkexpr(&expr, init); goto ret;
expr->type = n->type;
*np = expr;
return;
} }
if(t->etype == TSTRUCT && countfield(t) <= 4) { if(t->etype == TSTRUCT && countfield(t) <= 4) {
// Struct of four or fewer fields. // Struct of four or fewer fields.
// Inline comparisons. // Inline comparisons.
...@@ -3194,13 +3191,10 @@ walkcompare(Node **np, NodeList **init) ...@@ -3194,13 +3191,10 @@ walkcompare(Node **np, NodeList **init)
} }
if(expr == N) if(expr == N)
expr = nodbool(n->op == OEQ); expr = nodbool(n->op == OEQ);
typecheck(&expr, Erv); r = expr;
walkexpr(&expr, init); goto ret;
expr->type = n->type;
*np = expr;
return;
} }
// Chose not to inline, but still have addresses. // Chose not to inline, but still have addresses.
// Call equality function directly. // Call equality function directly.
// The equality function requires a bool pointer for // The equality function requires a bool pointer for
...@@ -3233,10 +3227,7 @@ walkcompare(Node **np, NodeList **init) ...@@ -3233,10 +3227,7 @@ walkcompare(Node **np, NodeList **init)
if(n->op != OEQ) if(n->op != OEQ)
r = nod(ONOT, r, N); r = nod(ONOT, r, N);
typecheck(&r, Erv); goto ret;
walkexpr(&r, init);
*np = r;
return;
hard: hard:
// Cannot take address of one or both of the operands. // Cannot take address of one or both of the operands.
...@@ -3252,7 +3243,16 @@ hard: ...@@ -3252,7 +3243,16 @@ hard:
r = mkcall1(fn, n->type, init, typename(n->left->type), l, r); r = mkcall1(fn, n->type, init, typename(n->left->type), l, r);
if(n->op == ONE) { if(n->op == ONE) {
r = nod(ONOT, r, N); r = nod(ONOT, r, N);
typecheck(&r, Erv); }
goto ret;
ret:
typecheck(&r, Erv);
walkexpr(&r, init);
if(r->type != n->type) {
r = nod(OCONVNOP, r, N);
r->type = n->type;
r->typecheck = 1;
} }
*np = r; *np = r;
return; return;
......
...@@ -387,6 +387,23 @@ func main() { ...@@ -387,6 +387,23 @@ func main() {
isfalse(iz != x) isfalse(iz != x)
} }
// named booleans
{
type mybool bool
var b mybool
type T struct{ data [20]byte }
var x, y T
b = x == y
istrue(x == y)
istrue(bool(b))
m := make(map[string][10]interface{})
b = m["x"] == m["y"]
istrue(m["x"] == m["y"])
istrue(bool(b))
}
shouldPanic(p1) shouldPanic(p1)
shouldPanic(p2) shouldPanic(p2)
shouldPanic(p3) shouldPanic(p3)
......
// compile
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// issue 7366: generates a temporary with ideal type
// during comparison of small structs.
package main
type T struct {
data [10]byte
}
func main() {
var a T
var b T
if a == b {
}
}
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