]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: avoid leak of dottype expression if type does not contain pointers.
authorTal Shprecher <tshprecher@gmail.com>
Sun, 14 Feb 2016 06:39:16 +0000 (22:39 -0800)
committerDavid Chase <drchase@google.com>
Fri, 19 Feb 2016 16:10:14 +0000 (16:10 +0000)
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>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/typecheck.go
test/escape_iface.go

index ff983e717edc722e3d2a9e4380d862277496f640..ccdb7810406b1fd7aee176b5250c815d4870344b 100644 (file)
@@ -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 {
index f74bb334aabf9271f68a4c89fd89292c2cdc8a72..8fd6f8557500a55d684364e1f27adf0b242668e6 100644 (file)
@@ -936,7 +936,6 @@ OpSwitch:
                        n.Type = n.Right.Type
                        n.Right = nil
                        if n.Type == nil {
-                               n.Type = nil
                                return
                        }
                }
index 2b1144ad2c5aa2d45c2f25832e1cd86118805b5c..9149fa17705e3e2f565077b564d4f725080c93a9 100644 (file)
@@ -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"
+       }
+}