mirror of
https://github.com/golang/go
synced 2024-11-23 05:00:07 -07:00
cmd/compile: fix recognition of unnamed return variables
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>
This commit is contained in:
parent
715d4e2e01
commit
063a91c0ab
@ -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
|
||||
|
@ -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)"}]}`)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user