]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: mark anonymous receiver parameters as non-escaping
authorMatthew Dempsky <mdempsky@google.com>
Wed, 7 Mar 2018 23:10:27 +0000 (15:10 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 8 Mar 2018 00:20:01 +0000 (00:20 +0000)
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: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/types/type.go
test/escape5.go

index 9c486e789889b158fddd7d213832bf8991f7724e..eed863aa13d8300117003c0b09b642594ee3fad5 100644 (file)
@@ -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)
+                       }
                }
        }
 }
index e62d324cdee225a66e2592299842e8288c14561e..87623a2cc30fe11fbfbe5f5c597e7616b771d5bd 100644 (file)
@@ -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,
index 7d6ef554a53fd0852330ab0b7d75820a3f1ddbf6..0bae1e840107c81525e3e4e1e4f30b3e2130ba00 100644 (file)
@@ -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"
+}