cmd/gc: fix defer copy(x, <-c)

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
This commit is contained in:
Russ Cox 2014-05-27 23:59:06 -04:00
parent daf9308066
commit ceb982e004
2 changed files with 30 additions and 8 deletions

View 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;

View file

@ -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])
}
}