]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: avoid leak of dottype expression on double assignment form
authorTal Shprecher <tshprecher@gmail.com>
Wed, 13 Jul 2016 18:29:39 +0000 (12:29 -0600)
committerDavid Chase <drchase@google.com>
Mon, 10 Oct 2016 12:09:16 +0000 (12:09 +0000)
This is a followup to issue #13805. That change avoid leaks for types that
don't have any pointers for the single assignment form of a dottype expression.
This does the same for the double assignment form.

Fixes #15796

Change-Id: I27474cade0ff1f3025cb6392f47b87b33542bc0f
Reviewed-on: https://go-review.googlesource.com/24906
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
test/escape_iface.go

index 6c377ea9cb21cdefbaab2786731d91430452116d..75ffe4d8010e3e8c3fa9e201f3a2d388d3acf6d1 100644 (file)
@@ -1120,7 +1120,6 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                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
-               ODOTTYPE2,
                OSLICE,
                OSLICE3,
                OSLICEARR,
@@ -1129,7 +1128,8 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                // Conversions, field access, slice all preserve the input value.
                escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
 
-       case ODOTTYPE:
+       case ODOTTYPE,
+               ODOTTYPE2:
                if src.Type != nil && !haspointers(src.Type) {
                        break
                }
index 50a5132d1def05bb3380df391458ac962ebe962e..8a11d7eb820dbef0ff2906696faa0a44ade64a43 100644 (file)
@@ -226,22 +226,36 @@ func dotTypeEscape() *T2 { // #11931
        }
 }
 
-func dotTypeEscape2() { // #13805
+func dotTypeEscape2() { // #13805, #15796
        {
                i := 0
+               j := 0
                var v int
+               var ok bool
                var x interface{} = i // ERROR "i does not escape"
+               var y interface{} = j // ERROR "j does not escape"
+
                *(&v) = x.(int) // ERROR "&v does not escape"
+               *(&v), *(&ok) = y.(int) // ERROR "&v does not escape" "&ok does not escape"
        }
        {
                i := 0
+               j := 0
+               var ok bool
                var x interface{} = i // ERROR "i does not escape"
-               sink = x.(int)        // ERROR "x.\(int\) escapes to heap"
+               var y interface{} = j // ERROR "j does not escape"
 
+               sink = x.(int)        // ERROR "x.\(int\) escapes to heap"
+               sink, *(&ok) = y.(int)     // ERROR "&ok does not escape"
        }
        {
                i := 0 // ERROR "moved to heap: i"
+               j := 0 // ERROR "moved to heap: j"
+               var ok bool
                var x interface{} = &i // ERROR "&i escapes to heap"
+               var y interface{} = &j // ERROR "&j escapes to heap"
+
                sink = x.(*int)        // ERROR "x.\(\*int\) escapes to heap"
+               sink, *(&ok) = y.(*int)     // ERROR "&ok does not escape"
        }
 }