fmt.Printf("%v:[%d] %v esc: %v\n", linestr(lineno), e.loopdepth, funcSym(Curfn), n)
}
+opSwitch:
switch n.Op {
// Record loop depth at declaration.
case ODCL:
// and keep the current loop depth.
if n.Left.Op == ONAME {
switch n.Left.Class() {
- case PAUTO:
- nE := e.nodeEscState(n)
- leftE := e.nodeEscState(n.Left)
- if leftE.Loopdepth != 0 {
- nE.Loopdepth = leftE.Loopdepth
- }
-
// PPARAM is loop depth 1 always.
// PPARAMOUT is loop depth 0 for writes
// but considered loop depth 1 for address-of,
case PPARAM, PPARAMOUT:
nE := e.nodeEscState(n)
nE.Loopdepth = 1
+ break opSwitch
}
}
+ nE := e.nodeEscState(n)
+ leftE := e.nodeEscState(n.Left)
+ if leftE.Loopdepth != 0 {
+ nE.Loopdepth = leftE.Loopdepth
+ }
+
+ case ODOT,
+ ODOTPTR,
+ OINDEX:
+ // Propagate the loopdepth of t to t.field.
+ if n.Left.Op != OLITERAL { // OLITERAL node doesn't have esc state
+ e.nodeEscState(n).Loopdepth = e.nodeEscState(n.Left).Loopdepth
+ }
}
lineno = lno
u.M() // ERROR "u does not escape"
u.N() // ERROR "u does not escape"
}
+
+// Issue 24730: taking address in a loop causes unnecessary escape
+type T24730 struct {
+ x [64]byte
+}
+
+func (t *T24730) g() { // ERROR "t does not escape"
+ y := t.x[:] // ERROR "t\.x does not escape"
+ for i := range t.x[:] { // ERROR "t\.x does not escape"
+ y = t.x[:] // ERROR "t\.x does not escape"
+ y[i] = 1
+ }
+
+ var z *byte
+ for i := range t.x[:] { // ERROR "t\.x does not escape"
+ z = &t.x[i] // ERROR "t\.x\[i\] does not escape"
+ *z = 2
+ }
+}