You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Execute the command $ go tool compile -m=2 example.go.
The output on tip is (important bits are in bold):
example.go:5:6: can inline param1 as: func(*int, *int) (*int, *int) { return p1, p2 }
example.go:9:6: can inline caller1 as: func() { i := 0; j := 0; sink, _ = param1(&i, &j) }
example.go:12:18: inlining call to param1 func(*int, *int) (*int, *int) { return p1, p2 }
example.go:5:13: leaking param: p1 to result ~r2 level=0
example.go:5:13: from ~r2 (return) at example.go:6:2
example.go:5:17: leaking param: p2 to result ~r3 level=0
example.go:5:17: from ~r3 (return) at example.go:6:2
example.go:12:10: (*int)(~r2) escapes to heap
example.go:12:10: from sink (assign-pair) at example.go:3:5
example.go:12:19: &i escapes to heap
example.go:12:19: from p1 (assign-pair) at example.go:12:18
example.go:12:19: from ~r2 (assign-pair) at example.go:12:18
example.go:12:19: from (*int)(~r2) (interface-converted) at example.go:12:10
example.go:12:19: from sink (assign-pair) at example.go:3:5
example.go:10:2: moved to heap: i
example.go:12:23: caller1 &j does not escape
Note that the assignment target is reported to be sink (correct) and the location is example.go:3:5 (not correct). During flow graph construction, it's clear that the location is example.go:12:10.
Before describing what's the reason behind that, we can compare OAS2 handling with OAS.
Here is slightly modified example:
example2.go:5:6: can inline caller1 as: func() { i := 0; sink = &i }
example2.go:7:7: &i escapes to heap
example2.go:7:7: from sink (assigned to top level variable) at example2.go:7:7
example2.go:7:9: &i escapes to heap
example2.go:7:9: from &i (interface-converted) at example2.go:7:7
example2.go:7:9: from sink (assigned to top level variable) at example2.go:7:7
example2.go:6:2: moved to heap: i
Nevermind that it prints &i escapes to heap twice, that's not relevant for this issue.
What is important is that it points to example2.go:7:7, the location where the assignment actually happens, not to the line where sink is declared.
Would be good to be consistent here and print assignment location for OAS too.
Note that n is OAS2, and inner n is an element from LHS and it shadows outer n.
So, instead of marking "assign-pair" with assignment position, we annotate it with LHS[i] position.
90% sure this is wrong and that error probably comes from copy/paste error (other e.escassignWhyWhere calls use n parameter as well, but there is no for loop that shadows it).
So, the proposed solution is to pass proper where argument to escassignWhyWhere.
Fixed output is:
example.go:5:6: can inline param1 as: func(*int, *int) (*int, *int) { return p1, p2 }
example.go:9:6: can inline caller1 as: func() { i := 0; j := 0; sink, _ = param1(&i, &j) }
example.go:12:18: inlining call to param1 func(*int, *int) (*int, *int) { return p1, p2 }
example.go:5:13: leaking param: p1 to result ~r2 level=0
example.go:5:13: from ~r2 (return) at example.go:6:2
example.go:5:17: leaking param: p2 to result ~r3 level=0
example.go:5:17: from ~r3 (return) at example.go:6:2
example.go:12:10: (*int)(~r2) escapes to heap
example.go:12:10: from sink (assign-pair) at example.go:12:10
example.go:12:19: &i escapes to heap
example.go:12:19: from p1 (assign-pair) at example.go:12:18
example.go:12:19: from ~r2 (assign-pair) at example.go:12:18
example.go:12:19: from (*int)(~r2) (interface-converted) at example.go:12:10
example.go:12:19: from sink (assign-pair) at example.go:12:10
example.go:10:2: moved to heap: i
example.go:12:23: caller1 &j does not escape
Note that now it points to example.go:12:10.
I find old output confusing and inconsistent, hence I'm proposing fixing it.
The text was updated successfully, but these errors were encountered:
cmd/compile/internal/gc: esc.go -m=2 reports invalid sink pos for some nodes
Given this code (extracted from
$GOROOT/test/escape_param.go
):Execute the command
$ go tool compile -m=2 example.go
.The output on tip is (important bits are in bold):
Note that the assignment target is reported to be
sink
(correct) and the location isexample.go:3:5
(not correct). During flow graph construction, it's clear that the location isexample.go:12:10
.Before describing what's the reason behind that, we can compare
OAS2
handling withOAS
.Here is slightly modified example:
The output for
-m2
is:Nevermind that it prints
&i escapes to heap
twice, that's not relevant for this issue.What is important is that it points to
example2.go:7:7
, the location where the assignment actually happens, not to the line wheresink
is declared.Would be good to be consistent here and print assignment location for
OAS
too.The code that causes problem is this:
Note that
n
isOAS2
, and innern
is an element from LHS and it shadows outern
.So, instead of marking "assign-pair" with assignment position, we annotate it with
LHS[i]
position.90% sure this is wrong and that error probably comes from copy/paste error (other
e.escassignWhyWhere
calls usen
parameter as well, but there is no for loop that shadows it).So, the proposed solution is to pass proper
where
argument toescassignWhyWhere
.Fixed output is:
Note that now it points to
example.go:12:10
.I find old output confusing and inconsistent, hence I'm proposing fixing it.
The text was updated successfully, but these errors were encountered: