From 672e57944458fc3c5f5ee1dd11d4f32d1aeaebe1 Mon Sep 17 00:00:00 2001 From: Tal Shprecher Date: Wed, 13 Jul 2016 12:29:39 -0600 Subject: [PATCH] cmd/compile: avoid leak of dottype expression on double assignment form 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 TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/gc/esc.go | 4 ++-- test/escape_iface.go | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 6c377ea9cb..75ffe4d801 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -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 } diff --git a/test/escape_iface.go b/test/escape_iface.go index 50a5132d1d..8a11d7eb82 100644 --- a/test/escape_iface.go +++ b/test/escape_iface.go @@ -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" } } -- 2.48.1