mirror of https://github.com/golang/go.git
cmd/compile: avoid leak of dottype expression if type does not contain pointers.
Fixes #13805 Change-Id: Ica9aae2e054b74f67d28ab27f72c52a3f03eeb59 Reviewed-on: https://go-review.googlesource.com/19489 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
c8e7b34b59
commit
5c5e8d4105
|
|
@ -962,7 +962,7 @@ func escassign(e *EscState, dst *Node, src *Node) {
|
|||
dst = &e.theSink
|
||||
}
|
||||
|
||||
case ODOT: // treat "dst.x = src" as "dst = src"
|
||||
case ODOT: // treat "dst.x = src" as "dst = src"
|
||||
escassign(e, dst.Left, src)
|
||||
|
||||
return
|
||||
|
|
@ -1042,7 +1042,6 @@ func escassign(e *EscState, dst *Node, src *Node) {
|
|||
ODOTMETH,
|
||||
// treat recv.meth as a value with recv in it, only happens in ODEFER and OPROC
|
||||
// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
|
||||
ODOTTYPE,
|
||||
ODOTTYPE2,
|
||||
OSLICE,
|
||||
OSLICE3,
|
||||
|
|
@ -1052,6 +1051,12 @@ func escassign(e *EscState, dst *Node, src *Node) {
|
|||
// Conversions, field access, slice all preserve the input value.
|
||||
escassign(e, dst, src.Left)
|
||||
|
||||
case ODOTTYPE:
|
||||
if src.Type != nil && !haspointers(src.Type) {
|
||||
break
|
||||
}
|
||||
escassign(e, dst, src.Left)
|
||||
|
||||
case OAPPEND:
|
||||
// Append returns first argument.
|
||||
// Subsequent arguments are already leaked because they are operands to append.
|
||||
|
|
@ -1549,9 +1554,9 @@ func escflows(e *EscState, dst *Node, src *Node) {
|
|||
// finding an OADDR just means we're following the upstream of a dereference,
|
||||
// so this address doesn't leak (yet).
|
||||
// If level == 0, it means the /value/ of this node can reach the root of this flood.
|
||||
// so if this node is an OADDR, it's argument should be marked as escaping iff
|
||||
// it's currfn/e->loopdepth are different from the flood's root.
|
||||
// Once an object has been moved to the heap, all of it's upstream should be considered
|
||||
// so if this node is an OADDR, its argument should be marked as escaping iff
|
||||
// its currfn/e->loopdepth are different from the flood's root.
|
||||
// Once an object has been moved to the heap, all of its upstream should be considered
|
||||
// escaping to the global scope.
|
||||
func escflood(e *EscState, dst *Node) {
|
||||
switch dst.Op {
|
||||
|
|
|
|||
|
|
@ -936,7 +936,6 @@ OpSwitch:
|
|||
n.Type = n.Right.Type
|
||||
n.Right = nil
|
||||
if n.Type == nil {
|
||||
n.Type = nil
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,3 +225,23 @@ func dotTypeEscape() *T2 { // #11931
|
|||
T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
|
||||
}
|
||||
}
|
||||
|
||||
func dotTypeEscape2() { // #13805
|
||||
{
|
||||
i := 0
|
||||
var v int
|
||||
var x interface{} = i // ERROR "i does not escape"
|
||||
*(&v) = x.(int) // ERROR "&v does not escape"
|
||||
}
|
||||
{
|
||||
i := 0
|
||||
var x interface{} = i // ERROR "i does not escape"
|
||||
sink = x.(int) // ERROR "x.\(int\) escapes to heap"
|
||||
|
||||
}
|
||||
{
|
||||
i := 0 // ERROR "moved to heap: i"
|
||||
var x interface{} = &i // ERROR "&i escapes to heap"
|
||||
sink = x.(*int) // ERROR "x.\(\*int\) escapes to heap"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue