1
0
mirror of https://github.com/golang/go synced 2024-11-22 22:20:03 -07:00

cmd/compile: fix order of map iteration in deadlocals

This makes builds reproducible again.

Fixes #68672
Updates #65158

Change-Id: I260180f52e992c702ab89050deb6484087ae265f
Reviewed-on: https://go-review.googlesource.com/c/go/+/602075
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
David Chase 2024-07-31 09:55:14 -04:00 committed by Gopher Robot
parent eea2e929fa
commit d32133af77

View File

@ -30,7 +30,8 @@ func Funcs(fns []*ir.Func) {
v := newVisitor(fn) v := newVisitor(fn)
v.nodes(fn.Body) v.nodes(fn.Body)
for _, assigns := range v.defs { for _, k := range v.defsKeys {
assigns := v.defs[k]
for _, as := range assigns { for _, as := range assigns {
// Kludge for "missing func info" linker panic. // Kludge for "missing func info" linker panic.
// See also closureInitLSym in inline/inl.go. // See also closureInitLSym in inline/inl.go.
@ -52,6 +53,7 @@ type visitor struct {
// defs[name] contains assignments that can be discarded if name can be discarded. // defs[name] contains assignments that can be discarded if name can be discarded.
// if defs[name] is defined nil, then name is actually used. // if defs[name] is defined nil, then name is actually used.
defs map[*ir.Name][]assign defs map[*ir.Name][]assign
defsKeys []*ir.Name // insertion order of keys, for reproducible iteration (and builds)
doNode func(ir.Node) bool doNode func(ir.Node) bool
} }
@ -96,9 +98,11 @@ func (v *visitor) node(n ir.Node) {
n = n.Canonical() n = n.Canonical()
if isLocal(n, false) { if isLocal(n, false) {
// Force any lazy definitions. // Force any lazy definitions.
s := v.defs[n] s, ok := v.defs[n]
if !ok {
v.defsKeys = append(v.defsKeys, n)
}
v.defs[n] = nil v.defs[n] = nil
for _, as := range s { for _, as := range s {
// do the visit that was skipped in v.assign when as was appended to v.defs[n] // do the visit that was skipped in v.assign when as was appended to v.defs[n]
v.node(*as.rhs) v.node(*as.rhs)
@ -161,6 +165,9 @@ func (v *visitor) assign(pos src.XPos, lhs, rhs *ir.Node, blankIsNotUse bool) {
if isLocal(name, blankIsNotUse) && !hasEffects(*rhs) { if isLocal(name, blankIsNotUse) && !hasEffects(*rhs) {
if s, ok := v.defs[name]; !ok || s != nil { if s, ok := v.defs[name]; !ok || s != nil {
// !ok || s != nil is FALSE if previously "v.defs[name] = nil" -- that marks a use. // !ok || s != nil is FALSE if previously "v.defs[name] = nil" -- that marks a use.
if !ok {
v.defsKeys = append(v.defsKeys, name)
}
v.defs[name] = append(s, assign{pos, lhs, rhs}) v.defs[name] = append(s, assign{pos, lhs, rhs})
return // don't visit rhs unless that node ends up live, later. return // don't visit rhs unless that node ends up live, later.
} }