mirror of
https://github.com/golang/go
synced 2024-11-11 21:20:21 -07: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:
parent
9419713528
commit
3042463d61
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user