diff options
author | Russ Cox <rsc@golang.org> | 2014-05-27 23:59:06 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-05-27 23:59:06 -0400 |
commit | ceb982e0049d7464413528ffab87ed0b34bfb56a (patch) | |
tree | 3b143cdd4c4e5c698ad00d075c5f2d9acfe18b35 | |
parent | daf9308066a71802ed723ba96459afe2558c62d9 (diff) | |
download | go-ceb982e0049d7464413528ffab87ed0b34bfb56a.tar.gz go-ceb982e0049d7464413528ffab87ed0b34bfb56a.zip |
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
-rw-r--r-- | src/cmd/gc/order.c | 15 | ||||
-rw-r--r-- | test/fixedbugs/issue8039.go | 23 |
2 files changed, 30 insertions, 8 deletions
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c index b9f2d35ce4..30dbc7dacc 100644 --- a/src/cmd/gc/order.c +++ b/src/cmd/gc/order.c @@ -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 index 0000000000..b13e474d9b --- /dev/null +++ b/test/fixedbugs/issue8039.go @@ -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]) + } +} |