]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix recognition of unnamed return variables
authorMatthew Dempsky <mdempsky@google.com>
Fri, 30 Oct 2020 19:58:28 +0000 (12:58 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Sun, 1 Nov 2020 01:06:56 +0000 (01:06 +0000)
In golang.org/cl/266199, I reused the existing code in inlining that
recognizes anonymous variables. However, it turns out that code
mistakenly recognizes anonymous return parameters as named when
inlining a function from the same package.

The issue is funcargs (which is only used for functions parsed from
source) synthesizes ~r names for anonymous return parameters, but
funcargs2 (which is only used for functions imported from export data)
does not.

This CL fixes the behavior so that anonymous return parameters are
handled identically whether a function is inlined within the same
package or across packages. It also adds a proper cross-package test
case demonstrating #33160 is fixed in both cases.

Change-Id: Iaa39a23f5666979a1f5ca6d09fc8c398e55b784c
Reviewed-on: https://go-review.googlesource.com/c/go/+/266719
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/logopt/logopt_test.go
test/fixedbugs/issue42284.dir/a.go
test/fixedbugs/issue42284.dir/b.go

index 8a5c6d86666f6f5e6e85dc0c91def641e0b82a5f..253036fea6417b8167f88a02877f59f1b2ca13e2 100644 (file)
@@ -1054,7 +1054,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        var retvars []*Node
        for i, t := range fn.Type.Results().Fields().Slice() {
                var m *Node
-               if n := asNode(t.Nname); n != nil && !n.isBlank() {
+               if n := asNode(t.Nname); n != nil && !n.isBlank() && !strings.HasPrefix(n.Sym.Name, "~r") {
                        m = inlvar(n)
                        m = typecheck(m, ctxExpr)
                        inlvars[n] = m
index fca85c10fbb38539f6ee0812ec228122d35720a5..51bab49518c079e09c84e813f9a3fb6c88d5af49 100644 (file)
@@ -213,15 +213,15 @@ func s15a8(x *[15]int64) [15]int64 {
                        `"relatedInformation":[`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:    flow: y = z:"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from y := z (assign-pair)"},`+
-                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:    flow: ~r1 = y:"},`+
+                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:    flow: ~R0 = y:"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from y.b (dot of pointer)"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from \u0026y.b (address-of)"},`+
                        `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":9},"end":{"line":4,"character":9}}},"message":"inlineLoc"},`+
-                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from ~r1 = \u003cN\u003e (assign-pair)"},`+
-                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:    flow: ~r2 = ~r1:"},`+
-                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:      from return (*int)(~r1) (return)"}]}`)
+                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow:      from ~R0 = \u003cN\u003e (assign-pair)"},`+
+                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:    flow: ~r2 = ~R0:"},`+
+                       `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow:      from return (*int)(~R0) (return)"}]}`)
        })
 }
 
index e1271af32d0d6ed86813663518e831fca61324e4..ffe9310be35b645165ab7b329f168703b9d9867e 100644 (file)
@@ -9,12 +9,19 @@ type T int
 
 func (T) M() {} // ERROR "can inline T.M"
 
+func E() I { // ERROR "can inline E"
+       return T(0) // ERROR "T\(0\) escapes to heap"
+}
+
 func F(i I) I { // ERROR "can inline F" "leaking param: i to result ~r1 level=0"
        i = nil
        return i
 }
 
-func g() { // ERROR "can inline g"
+func g() {
+       h := E() // ERROR "inlining call to E" "T\(0\) does not escape"
+       h.M()    // ERROR "devirtualizing h.M to T"
+
        // BAD: T(0) could be stack allocated.
        i := F(T(0)) // ERROR "inlining call to F" "T\(0\) escapes to heap"
 
index 3305166db063ec305c0b42ca1c8dcc718d1d1851..652aa3212265a32964a027582abab46790f84fc1 100644 (file)
@@ -6,7 +6,10 @@ package b
 
 import "./a"
 
-func g() { // ERROR "can inline g"
+func g() {
+       h := a.E() // ERROR "inlining call to a.E" "a.I\(a.T\(0\)\) does not escape"
+       h.M()      // ERROR "devirtualizing h.M to a.T"
+
        // BAD: T(0) could be stack allocated.
        i := a.F(a.T(0)) // ERROR "inlining call to a.F" "a.T\(0\) escapes to heap"