Commit 88466e93 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: mark anonymous receiver parameters as non-escaping

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 <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8b8625a3
...@@ -2259,16 +2259,18 @@ func (e *EscState) esctag(fn *Node) { ...@@ -2259,16 +2259,18 @@ func (e *EscState) esctag(fn *Node) {
// Unnamed parameters are unused and therefore do not escape. // Unnamed parameters are unused and therefore do not escape.
// (Unnamed parameters are not in the Dcl list in the loop above // (Unnamed parameters are not in the Dcl list in the loop above
// so we need to mark them separately.) // so we need to mark them separately.)
for _, f := range fn.Type.Params().Fields().Slice() { for _, fs := range types.RecvsParams {
if !types.Haspointers(f.Type) { // don't bother tagging for scalars for _, f := range fs(fn.Type).Fields().Slice() {
continue if !types.Haspointers(f.Type) { // don't bother tagging for scalars
} continue
if f.Note == uintptrEscapesTag { }
// Note is already set in the loop above. if f.Note == uintptrEscapesTag {
continue // Note is already set in the loop above.
} continue
if f.Sym == nil || f.Sym.IsBlank() { }
f.Note = mktag(EscNone) if f.Sym == nil || f.Sym.IsBlank() {
f.Note = mktag(EscNone)
}
} }
} }
} }
...@@ -726,6 +726,11 @@ var RecvsParamsResults = [3]func(*Type) *Type{ ...@@ -726,6 +726,11 @@ var RecvsParamsResults = [3]func(*Type) *Type{
(*Type).Recvs, (*Type).Params, (*Type).Results, (*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. // ParamsResults is like RecvsParamsResults, but omits receiver parameters.
var ParamsResults = [2]func(*Type) *Type{ var ParamsResults = [2]func(*Type) *Type{
(*Type).Params, (*Type).Results, (*Type).Params, (*Type).Results,
......
...@@ -163,3 +163,15 @@ func f13() { ...@@ -163,3 +163,15 @@ func f13() {
f12(&x) // ERROR "&x does not escape" f12(&x) // ERROR "&x does not escape"
runtime.KeepAlive(&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"
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment