Commit 5c5e8d41 authored by Tal Shprecher's avatar Tal Shprecher Committed by David Chase

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: default avatarDavid Chase <drchase@google.com>
parent c8e7b34b
......@@ -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"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment