]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/gc: fix walkcompare bugs.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 24 Feb 2014 18:51:59 +0000 (19:51 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 24 Feb 2014 18:51:59 +0000 (19:51 +0100)
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

src/cmd/gc/walk.c
test/cmp.go
test/fixedbugs/issue7366.go [new file with mode: 0644]

index 97473de0715b68ffe1adeb0dabaaf7476739cea3..068e38cf3ba69f088a7fc8145abee533233674d4 100644 (file)
@@ -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;
index 73de502f39fcb54ccdbe6e90e536391ea5974343..9ac0ebe79d3dc00d217f1bec75adc71f7889445a 100644 (file)
@@ -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)
diff --git a/test/fixedbugs/issue7366.go b/test/fixedbugs/issue7366.go
new file mode 100644 (file)
index 0000000..754da6f
--- /dev/null
@@ -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 {
+       }
+}