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 <khr@golang.org>
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Martin Möhrmann 2016-12-19 00:06:46 +01:00
parent 55310403dd
commit a8f07310e3
2 changed files with 42 additions and 9 deletions

View file

@ -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))
}
}
}

View file

@ -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() {