From: Martin Möhrmann Date: Sun, 18 Dec 2016 23:06:46 +0000 (+0100) Subject: cmd/compile: fix assignment order in string range loop X-Git-Tag: go1.9beta1~1404 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a8f07310e3a08910dde2b7e9550848ec400753ad;p=gostls13.git cmd/compile: fix assignment order in string range loop Fixes #18376. Change-Id: I4fe24f479311cd4cd1bdad9a966b681e50e3d500 Reviewed-on: https://go-review.googlesource.com/35955 Reviewed-by: Keith Randall Run-TryBot: Martin Möhrmann TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 99ecdd3cc5..d1ac5780a0 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -156,6 +156,10 @@ func walkrange(n *Node) { v2 = n.List.Second() } + if v1 == nil && v2 != nil { + Fatalf("walkrange: v2 != nil while v1 == nil") + } + // n.List has no meaning anymore, clear it // to avoid erroneous processing by racewalk. n.List.Set(nil) @@ -290,14 +294,14 @@ func walkrange(n *Node) { // // ha := a // for hv1 := 0; hv1 < len(ha); { - // v1 = hv1 + // hv1t := hv1 // hv2 := rune(ha[hv1]) // if hv2 < utf8.RuneSelf { // hv1++ // } else { // hv2, hv1 = decoderune(ha, hv1) // } - // v2 = hv2 + // v1, v2 = hv1t, hv2 // // original body // } @@ -305,6 +309,7 @@ func walkrange(n *Node) { ha := a hv1 := temp(Types[TINT]) + hv1t := temp(Types[TINT]) hv2 := temp(runetype) // hv1 := 0 @@ -314,18 +319,18 @@ func walkrange(n *Node) { n.Left = nod(OLT, hv1, nod(OLEN, ha, nil)) if v1 != nil { - // v1 = hv1 - body = append(body, nod(OAS, v1, hv1)) + // hv1t = hv1 + body = append(body, nod(OAS, hv1t, hv1)) } - // hv2 := ha[hv1] + // hv2 := rune(ha[hv1]) nind := nod(OINDEX, ha, hv1) nind.Bounded = true body = append(body, nod(OAS, hv2, conv(nind, runetype))) // if hv2 < utf8.RuneSelf nif := nod(OIF, nil, nil) - nif.Left = nod(OLT, nind, nodintconst(utf8.RuneSelf)) + nif.Left = nod(OLT, hv2, nodintconst(utf8.RuneSelf)) // hv1++ nif.Nbody.Set1(nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)))) @@ -341,9 +346,17 @@ func walkrange(n *Node) { body = append(body, nif) - if v2 != nil { - // v2 = hv2 - body = append(body, nod(OAS, v2, hv2)) + if v1 != nil { + if v2 != nil { + // v1, v2 = hv1t, hv2 + a := nod(OAS2, nil, nil) + a.List.Set2(v1, v2) + a.Rlist.Set2(hv1t, hv2) + body = append(body, a) + } else { + // v1 = hv1t + body = append(body, nod(OAS, v1, hv1t)) + } } } diff --git a/test/range.go b/test/range.go index bae7a1c3c9..afdac57fa3 100644 --- a/test/range.go +++ b/test/range.go @@ -277,6 +277,26 @@ func teststring() { println("wrong sum ranging over makestring", s) panic("fail") } + + x := []rune{'a', 'b'} + i := 1 + for i, x[i] = range "c" { + break + } + if i != 0 || x[0] != 'a' || x[1] != 'c' { + println("wrong parallel assignment", i, x[0], x[1]) + panic("fail") + } + + y := []int{1, 2, 3} + r := rune(1) + for y[r], r = range "\x02" { + break + } + if r != 2 || y[0] != 1 || y[1] != 0 || y[2] != 3 { + println("wrong parallel assignment", r, y[0], y[1], y[2]) + panic("fail") + } } func teststring1() {