From 920ebab03cbd101c71a27b90e170111447c6bbf8 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 13 Jun 2012 16:24:21 -0400 Subject: [PATCH] [release-branch.go1] cmd/gc: fix parallel assignment in range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ««« backport 2252777854d2 cmd/gc: fix parallel assignment in range for expr1, expr2 = range slice was assigning to expr1 and expr2 in sequence instead of in parallel. Now it assigns in parallel, as it should. This matters for things like for i, x[i] = range slice. Fixes #3464. R=ken2 CC=golang-dev https://golang.org/cl/6252048 »»» --- src/cmd/gc/range.c | 11 ++++++++--- src/cmd/gc/subr.c | 6 ++++++ test/range.go | 11 +++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c index 9bcd833a70..d301e4e4f1 100644 --- a/src/cmd/gc/range.c +++ b/src/cmd/gc/range.c @@ -152,9 +152,14 @@ walkrange(Node *n) n->ntest = nod(OLT, hv1, hn); n->nincr = nod(OASOP, hv1, nodintconst(1)); n->nincr->etype = OADD; - body = list1(nod(OAS, v1, hv1)); - if(v2) { - body = list(body, nod(OAS, v2, nod(OIND, hp, N))); + if(v2 == N) + body = list1(nod(OAS, v1, hv1)); + else { + a = nod(OAS2, N, N); + a->list = list(list1(v1), v2); + a->rlist = list(list1(hv1), nod(OIND, hp, N)); + body = list1(a); + tmp = nod(OADD, hp, nodintconst(t->type->width)); tmp->type = hp->type; tmp->typecheck = 1; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 681c023a01..fbff7a36b2 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1945,6 +1945,12 @@ safeexpr(Node *n, NodeList **init) if(n == N) return N; + if(n->ninit) { + walkstmtlist(n->ninit); + *init = concat(*init, n->ninit); + n->ninit = nil; + } + switch(n->op) { case ONAME: case OLITERAL: diff --git a/test/range.go b/test/range.go index b0f3ae605a..68b0c9a2f3 100644 --- a/test/range.go +++ b/test/range.go @@ -58,6 +58,17 @@ func testslice() { println("wrong sum ranging over makeslice") panic("fail") } + + x := []int{10, 20} + y := []int{99} + i := 1 + for i, x[i] = range y { + break + } + if i != 0 || x[0] != 10 || x[1] != 99 { + println("wrong parallel assignment", i, x[0], x[1]) + panic("fail") + } } func testslice1() {