// 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)
+ }
}
}
}
(*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,
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"
+}