mirror of
https://github.com/golang/go
synced 2024-11-23 05:00:07 -07:00
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:
parent
daf9308066
commit
ceb982e004
@ -409,14 +409,13 @@ ordercallargs(NodeList **l, Order *order)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ordercall orders the call expression n.
|
// 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
|
static void
|
||||||
ordercall(Node *n, Order *order, int special)
|
ordercall(Node *n, Order *order)
|
||||||
{
|
{
|
||||||
orderexpr(&n->left, order);
|
orderexpr(&n->left, order);
|
||||||
|
orderexpr(&n->right, order); // ODDDARG temp
|
||||||
ordercallargs(&n->list, order);
|
ordercallargs(&n->list, order);
|
||||||
if(!special)
|
|
||||||
orderexpr(&n->right, order); // ODDDARG temp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ordermapassign appends n to order->out, introducing temporaries
|
// 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.
|
// Special: avoid copy of func call n->rlist->n.
|
||||||
t = marktemp(order);
|
t = marktemp(order);
|
||||||
orderexprlist(n->list, order);
|
orderexprlist(n->list, order);
|
||||||
ordercall(n->rlist->n, order, 0);
|
ordercall(n->rlist->n, order);
|
||||||
ordermapassign(n, order);
|
ordermapassign(n, order);
|
||||||
cleantemp(t, order);
|
cleantemp(t, order);
|
||||||
break;
|
break;
|
||||||
@ -631,7 +630,7 @@ orderstmt(Node *n, Order *order)
|
|||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
// Special: handle call arguments.
|
// Special: handle call arguments.
|
||||||
t = marktemp(order);
|
t = marktemp(order);
|
||||||
ordercall(n, order, 0);
|
ordercall(n, order);
|
||||||
order->out = list(order->out, n);
|
order->out = list(order->out, n);
|
||||||
cleantemp(t, order);
|
cleantemp(t, order);
|
||||||
break;
|
break;
|
||||||
@ -652,7 +651,7 @@ orderstmt(Node *n, Order *order)
|
|||||||
poptemp(t1, order);
|
poptemp(t1, order);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ordercall(n->left, order, 1);
|
ordercall(n->left, order);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
order->out = list(order->out, n);
|
order->out = list(order->out, n);
|
||||||
@ -1023,7 +1022,7 @@ orderexpr(Node **np, Order *order)
|
|||||||
case OCALLINTER:
|
case OCALLINTER:
|
||||||
case OAPPEND:
|
case OAPPEND:
|
||||||
case OCOMPLEX:
|
case OCOMPLEX:
|
||||||
ordercall(n, order, 0);
|
ordercall(n, order);
|
||||||
n = ordercopyexpr(n, n->type, order, 0);
|
n = ordercopyexpr(n, n->type, order, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
23
test/fixedbugs/issue8039.go
Normal file
23
test/fixedbugs/issue8039.go
Normal 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])
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user