diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 42159505767..fcb4e96a75c 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -715,6 +715,7 @@ func (e *EscState) esc(n *Node, parent *Node) { 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: @@ -1000,13 +1001,6 @@ func (e *EscState) esc(n *Node, parent *Node) { // 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, @@ -1016,8 +1010,22 @@ func (e *EscState) esc(n *Node, parent *Node) { 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 diff --git a/test/escape5.go b/test/escape5.go index 0bae1e84010..d02f735f8fc 100644 --- a/test/escape5.go +++ b/test/escape5.go @@ -175,3 +175,22 @@ func _() { 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 + } +}