mirror of
https://github.com/golang/go
synced 2024-11-11 19:31:37 -07:00
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
This commit is contained in:
parent
ff15e5c00f
commit
14b0af4272
@ -3171,13 +3171,10 @@ walkcompare(Node **np, NodeList **init)
|
||||
}
|
||||
if(expr == N)
|
||||
expr = nodbool(n->op == OEQ);
|
||||
typecheck(&expr, Erv);
|
||||
walkexpr(&expr, init);
|
||||
expr->type = n->type;
|
||||
*np = expr;
|
||||
return;
|
||||
r = expr;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
|
||||
if(t->etype == TSTRUCT && countfield(t) <= 4) {
|
||||
// Struct of four or fewer fields.
|
||||
// Inline comparisons.
|
||||
@ -3194,13 +3191,10 @@ walkcompare(Node **np, NodeList **init)
|
||||
}
|
||||
if(expr == N)
|
||||
expr = nodbool(n->op == OEQ);
|
||||
typecheck(&expr, Erv);
|
||||
walkexpr(&expr, init);
|
||||
expr->type = n->type;
|
||||
*np = expr;
|
||||
return;
|
||||
r = expr;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
|
||||
// Chose not to inline, but still have addresses.
|
||||
// Call equality function directly.
|
||||
// The equality function requires a bool pointer for
|
||||
@ -3233,10 +3227,7 @@ walkcompare(Node **np, NodeList **init)
|
||||
|
||||
if(n->op != OEQ)
|
||||
r = nod(ONOT, r, N);
|
||||
typecheck(&r, Erv);
|
||||
walkexpr(&r, init);
|
||||
*np = r;
|
||||
return;
|
||||
goto ret;
|
||||
|
||||
hard:
|
||||
// Cannot take address of one or both of the operands.
|
||||
@ -3252,7 +3243,16 @@ hard:
|
||||
r = mkcall1(fn, n->type, init, typename(n->left->type), l, r);
|
||||
if(n->op == ONE) {
|
||||
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;
|
||||
return;
|
||||
|
17
test/cmp.go
17
test/cmp.go
@ -387,6 +387,23 @@ func main() {
|
||||
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(p2)
|
||||
shouldPanic(p3)
|
||||
|
21
test/fixedbugs/issue7366.go
Normal file
21
test/fixedbugs/issue7366.go
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 {
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user