1
0
mirror of https://github.com/golang/go synced 2024-11-25 02:57:57 -07:00

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
This commit is contained in:
Russ Cox 2012-05-24 23:05:36 -04:00
parent bf18d57d4a
commit 51072eb1fb
3 changed files with 25 additions and 3 deletions

View File

@ -152,9 +152,14 @@ walkrange(Node *n)
n->ntest = nod(OLT, hv1, hn); n->ntest = nod(OLT, hv1, hn);
n->nincr = nod(OASOP, hv1, nodintconst(1)); n->nincr = nod(OASOP, hv1, nodintconst(1));
n->nincr->etype = OADD; n->nincr->etype = OADD;
body = list1(nod(OAS, v1, hv1)); if(v2 == N)
if(v2) { body = list1(nod(OAS, v1, hv1));
body = list(body, nod(OAS, v2, nod(OIND, hp, N))); 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 = nod(OADD, hp, nodintconst(t->type->width));
tmp->type = hp->type; tmp->type = hp->type;
tmp->typecheck = 1; tmp->typecheck = 1;

View File

@ -1950,6 +1950,12 @@ safeexpr(Node *n, NodeList **init)
if(n == N) if(n == N)
return N; return N;
if(n->ninit) {
walkstmtlist(n->ninit);
*init = concat(*init, n->ninit);
n->ninit = nil;
}
switch(n->op) { switch(n->op) {
case ONAME: case ONAME:
case OLITERAL: case OLITERAL:

View File

@ -58,6 +58,17 @@ func testslice() {
println("wrong sum ranging over makeslice") println("wrong sum ranging over makeslice")
panic("fail") 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() { func testslice1() {