]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fix defer copy(x, <-c)
authorRuss Cox <rsc@golang.org>
Wed, 28 May 2014 03:59:06 +0000 (23:59 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 28 May 2014 03:59:06 +0000 (23:59 -0400)
In the first very rough draft of the reordering code
that was introduced in the Go 1.3 cycle, the pre-allocated
temporary for a ... argument was held in n->right.
It moved to n->alloc but the code avoiding n->right
was left behind in order.c. In copy(x, <-c), the receive
is in n->right and must be processed. Delete the special
case code, removing the bug.

Fixes #8039.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/100820044

src/cmd/gc/order.c
test/fixedbugs/issue8039.go [new file with mode: 0644]

index b9f2d35ce4dca318ba1087ee3de3f7ff08c422ad..30dbc7dacc1eecd20d67ff7af2b76ba9d8f61ca3 100644 (file)
@@ -409,14 +409,13 @@ ordercallargs(NodeList **l, Order *order)
 }
 
 // Ordercall orders the call expression n.
-// n->op is  OCALLMETH/OCALLFUNC/OCALLINTER.
+// n->op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
 static void
-ordercall(Node *n, Order *order, int special)
+ordercall(Node *n, Order *order)
 {
        orderexpr(&n->left, order);
+       orderexpr(&n->right, order); // ODDDARG temp
        ordercallargs(&n->list, order);
-       if(!special)
-               orderexpr(&n->right, order); // ODDDARG temp
 }
 
 // Ordermapassign appends n to order->out, introducing temporaries
@@ -580,7 +579,7 @@ orderstmt(Node *n, Order *order)
                // Special: avoid copy of func call n->rlist->n.
                t = marktemp(order);
                orderexprlist(n->list, order);
-               ordercall(n->rlist->n, order, 0);
+               ordercall(n->rlist->n, order);
                ordermapassign(n, order);
                cleantemp(t, order);
                break;
@@ -631,7 +630,7 @@ orderstmt(Node *n, Order *order)
        case OCALLMETH:
                // Special: handle call arguments.
                t = marktemp(order);
-               ordercall(n, order, 0);
+               ordercall(n, order);
                order->out = list(order->out, n);
                cleantemp(t, order);
                break;
@@ -652,7 +651,7 @@ orderstmt(Node *n, Order *order)
                        poptemp(t1, order);
                        break;
                default:
-                       ordercall(n->left, order, 1);
+                       ordercall(n->left, order);
                        break;
                }
                order->out = list(order->out, n);
@@ -1023,7 +1022,7 @@ orderexpr(Node **np, Order *order)
        case OCALLINTER:
        case OAPPEND:
        case OCOMPLEX:
-               ordercall(n, order, 0);
+               ordercall(n, order);
                n = ordercopyexpr(n, n->type, order, 0);
                break;
 
diff --git a/test/fixedbugs/issue8039.go b/test/fixedbugs/issue8039.go
new file mode 100644 (file)
index 0000000..b13e474
--- /dev/null
@@ -0,0 +1,23 @@
+// run
+
+// 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 8039. defer copy(x, <-c) did not rewrite <-c properly.
+
+package main
+
+func f(s []int) {
+       c := make(chan []int, 1)
+       c <- []int{1}
+       defer copy(s, <-c)
+}
+
+func main() {
+       x := make([]int, 1)
+       f(x)
+       if x[0] != 1 {
+               println("BUG", x[0])
+       }
+}