]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/gc: fix parallel assignment in range
authorRuss Cox <rsc@golang.org>
Fri, 25 May 2012 03:05:36 +0000 (23:05 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 25 May 2012 03:05:36 +0000 (23:05 -0400)
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
src/cmd/gc/subr.c
test/range.go

index 8e9d1afc5b7ca8193b138fab461d4fc976d5ce11..459105ee88d3abaeedc57ec0865b9b58a92b9c1a 100644 (file)
@@ -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;
index 0fee277fc7462231d806010bd688ed67e2d53d97..dfab86864a967832b7938fe24e6cb4db84905d14 100644 (file)
@@ -1950,6 +1950,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:
index b0f3ae605a9b103ad6d6c91a25ec875e2e9cd08a..68b0c9a2f3362be907da60e6fb25c207a4df98f9 100644 (file)
@@ -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() {