Skip to content

Commit

Permalink
cmd/compile: mark anonymous receiver parameters as non-escaping
Browse files Browse the repository at this point in the history
This was already done for normal parameters, and the same logic
applies for receiver parameters too.

Updates #24305.

Change-Id: Ia2a46f68d14e8fb62004ff0da1db0f065a95a1b7
Reviewed-on: https://go-review.googlesource.com/99335
Run-TryBot: Matthew Dempsky <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Brad Fitzpatrick <[email protected]>
  • Loading branch information
mdempsky committed Mar 8, 2018
1 parent 8b8625a commit 88466e9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/cmd/compile/internal/gc/esc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2259,16 +2259,18 @@ func (e *EscState) esctag(fn *Node) {
// Unnamed parameters are unused and therefore do not escape.
// (Unnamed parameters are not in the Dcl list in the loop above
// so we need to mark them separately.)
for _, f := range fn.Type.Params().Fields().Slice() {
if !types.Haspointers(f.Type) { // don't bother tagging for scalars
continue
}
if f.Note == uintptrEscapesTag {
// Note is already set in the loop above.
continue
}
if f.Sym == nil || f.Sym.IsBlank() {
f.Note = mktag(EscNone)
for _, fs := range types.RecvsParams {
for _, f := range fs(fn.Type).Fields().Slice() {
if !types.Haspointers(f.Type) { // don't bother tagging for scalars
continue
}
if f.Note == uintptrEscapesTag {
// Note is already set in the loop above.
continue
}
if f.Sym == nil || f.Sym.IsBlank() {
f.Note = mktag(EscNone)
}
}
}
}
5 changes: 5 additions & 0 deletions src/cmd/compile/internal/types/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,11 @@ var RecvsParamsResults = [3]func(*Type) *Type{
(*Type).Recvs, (*Type).Params, (*Type).Results,
}

// RecvsParams is like RecvsParamsResults, but omits result parameters.
var RecvsParams = [2]func(*Type) *Type{
(*Type).Recvs, (*Type).Params,
}

// ParamsResults is like RecvsParamsResults, but omits receiver parameters.
var ParamsResults = [2]func(*Type) *Type{
(*Type).Params, (*Type).Results,
Expand Down
12 changes: 12 additions & 0 deletions test/escape5.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,15 @@ func f13() {
f12(&x) // ERROR "&x does not escape"
runtime.KeepAlive(&x) // ERROR "&x does not escape"
}

// Test for issue 24305 (passing to unnamed receivers does not escape).
type U int

func (*U) M() {}
func (_ *U) N() {}

func _() {
var u U
u.M() // ERROR "u does not escape"
u.N() // ERROR "u does not escape"
}

0 comments on commit 88466e9

Please sign in to comment.