s.addNamedValue(left, right)
return
}
- // Left is not ssa-able. Compute its address.
- if left.Op == ONAME && left.Class() != PEXTERN && skip == 0 {
- s.vars[&memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, left, s.mem(), !left.IsAutoTmp())
+
+ // If this assignment clobbers an entire local variable, then emit
+ // OpVarDef so liveness analysis knows the variable is redefined.
+ if base := clobberBase(left); base.Op == ONAME && base.Class() != PEXTERN && skip == 0 {
+ s.vars[&memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !base.IsAutoTmp())
}
+
+ // Left is not ssa-able. Compute its address.
addr := s.addr(left, false)
if isReflectHeaderDataField(left) {
// Package unsafe's documentation says storing pointers into
return 0
}
}
+
+func clobberBase(n *Node) *Node {
+ if n.Op == ODOT && n.Left.Type.NumFields() == 1 {
+ return clobberBase(n.Left)
+ }
+ if n.Op == OINDEX && n.Left.Type.IsArray() && n.Left.Type.NumElem() == 1 {
+ return clobberBase(n.Left)
+ }
+ return n
+}
func good40() {
ret := T40{} // ERROR "stack object ret T40$"
- ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+ ret$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
+ ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
t := &ret
printnl() // ERROR "live at call to printnl: ret$"
// Note: ret is live at the printnl because the compiler moves &ret
//go:noescape
func f43(a []*int)
+
+// Assigning to a sub-element that makes up an entire local variable
+// should clobber that variable.
+func f44(f func() [2]*int) interface{} { // ERROR "live at entry to f44: f"
+ type T struct {
+ s [1][2]*int
+ }
+ ret := T{}
+ ret.s[0] = f()
+ return ret // ERROR "stack object .autotmp_5 T"
+}
}
func bad40() {
- t := newT40() // ERROR "live at call to makemap: ret$" "stack object ret T40$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
+ t := newT40() // ERROR "stack object ret T40$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
printnl() // ERROR "live at call to printnl: ret$"
useT40(t)
}
func good40() {
ret := T40{} // ERROR "stack object ret T40$"
- ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: ret$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
+ ret.m = make(map[int]int, 42) // ERROR "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
t := &ret
printnl() // ERROR "live at call to printnl: ret$"
useT40(t)