1
0
mirror of https://github.com/golang/go synced 2024-07-05 09:50:19 +00:00

cmd/compile: in escape analysis, use element type for OIND of slice

The escape analysis models the flow of "content" of X with a
level of "indirection" (OIND node) of X. This content can be
pointer dereference, or slice/string element. For the latter
case, the type of the OIND node should be the element type of
the slice/string. This CL fixes this. In particular, this
matters when the element type is pointerless, where the data
flow should not cause any escape.

Fixes #15730.

Change-Id: Iba9f92898681625e7e3ddef76ae65d7cd61c41e0
Reviewed-on: https://go-review.googlesource.com/107597
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cherry Zhang 2018-04-17 16:28:13 -04:00
parent 9419713528
commit 3042463d61
2 changed files with 39 additions and 3 deletions

View File

@ -1405,11 +1405,13 @@ func (e *EscState) addDereference(n *Node) *Node {
e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth
ind.Pos = n.Pos
t := n.Type
if t.IsKind(types.Tptr) {
if t.IsKind(types.Tptr) || t.IsSlice() {
// This should model our own sloppy use of OIND to encode
// decreasing levels of indirection; i.e., "indirecting" an array
// might yield the type of an element. To be enhanced...
// decreasing levels of indirection; i.e., "indirecting" a slice
// yields the type of an element.
t = t.Elem()
} else if t.IsString() {
t = types.Types[TUINT8]
}
ind.Type = t
return ind

View File

@ -194,3 +194,37 @@ func (t *T24730) g() { // ERROR "t does not escape"
*z = 2
}
}
// Issue 15730: copy causes unnecessary escape
var sink []byte
var sink2 []int
var sink3 []*int
func f15730a(args ...interface{}) { // ERROR "args does not escape"
for _, arg := range args {
switch a := arg.(type) {
case string:
copy(sink, a)
}
}
}
func f15730b(args ...interface{}) { // ERROR "args does not escape"
for _, arg := range args {
switch a := arg.(type) {
case []int:
copy(sink2, a)
}
}
}
func f15730c(args ...interface{}) { // ERROR "leaking param content: args"
for _, arg := range args {
switch a := arg.(type) {
case []*int:
// copy pointerful data should cause escape
copy(sink3, a)
}
}
}