go/test/fixedbugs/issue23017.go
Matthew Dempsky 907a4bfdc7 [dev.regabi] cmd/compile: fix map assignment order
After the previous cleanup/optimization CLs, ascompatee now correctly
handles map assignments too. So remove the code from order.mapAssign,
which causes us to assign to the map at the wrong point during
execution. It's not every day you get to fix an issue by only removing
code.

Thanks to Cuong Manh Le for test cases and continually following up on
this issue.

Passes toolstash -cmp. (Apparently the standard library never uses
tricky map assignments. Go figure.)

Fixes #23017.

Change-Id: Ie0728103d59d884d00c1c050251290a2a46150f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/281172
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-03 19:48:18 +00:00

114 lines
1.5 KiB
Go

// run
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// assignment order in multiple assignments.
// See issue #23017
package main
import "fmt"
func main() {}
func init() {
var m = map[int]int{}
var p *int
defer func() {
recover()
check(1, len(m))
check(42, m[2])
}()
m[2], *p = 42, 2
}
func init() {
var m = map[int]int{}
p := []int{}
defer func() {
recover()
check(1, len(m))
check(2, m[2])
}()
m[2], p[1] = 2, 2
}
func init() {
type P struct{ i int }
var m = map[int]int{}
var p *P
defer func() {
recover()
check(1, len(m))
check(3, m[2])
}()
m[2], p.i = 3, 2
}
func init() {
type T struct{ i int }
var x T
p := &x
p, p.i = new(T), 4
check(4, x.i)
}
func init() {
var m map[int]int
var a int
var p = &a
defer func() {
recover()
check(5, *p)
}()
*p, m[2] = 5, 2
}
var g int
func init() {
var m map[int]int
defer func() {
recover()
check(0, g)
}()
m[0], g = 1, 2
}
func init() {
type T struct{ x struct{ y int } }
var x T
p := &x
p, p.x.y = new(T), 7
check(7, x.x.y)
check(0, p.x.y)
}
func init() {
type T *struct{ x struct{ y int } }
x := struct{ y int }{0}
var q T = &struct{ x struct{ y int } }{x}
p := q
p, p.x.y = nil, 7
check(7, q.x.y)
}
func init() {
x, y := 1, 2
x, y = y, x
check(2, x)
check(1, y)
}
func check(want, got int) {
if want != got {
panic(fmt.Sprintf("wanted %d, but got %d", want, got))
}
}