From 95d7ce9ab1dea5dface92736305470965a41f61e Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 29 Jun 2022 17:16:46 -0700 Subject: [PATCH] [dev.unified] test: break escape_iface.go into unified/nounified variants The assignment `sink, *(&ok) = y.(int)` should (and does) escape a value to the heap, but this detail is missed because the implicit conversion of the multi-value expression `y.(int)` isn't visible to escape analysis (because it's not inserted until desugaring during walk). For Unified IR, I plan to apply this desugaring earlier (because it's necessary for correct dictionary handling), which means we'll now (correctly) report the heap escape. Due to limitations of the $GOROOT/test harness, the easiest way to handle that GOEXPERIMENT=unified gets this right while GOEXPERIMENT=nounified does not is to split the test case into separate files. Hence this CL. Change-Id: I91f3a6c015cbc646ab018747e152cac2874cf24c Reviewed-on: https://go-review.googlesource.com/c/go/+/415241 Reviewed-by: Cuong Manh Le Run-TryBot: Matthew Dempsky TryBot-Result: Gopher Robot Reviewed-by: David Chase --- test/escape_iface.go | 10 ---------- test/escape_iface_nounified.go | 25 +++++++++++++++++++++++++ test/escape_iface_unified.go | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 test/escape_iface_nounified.go create mode 100644 test/escape_iface_unified.go diff --git a/test/escape_iface.go b/test/escape_iface.go index dba08e3cb33b3..986228129a698 100644 --- a/test/escape_iface.go +++ b/test/escape_iface.go @@ -234,16 +234,6 @@ func dotTypeEscape2() { // #13805, #15796 *(&v) = x.(int) *(&v), *(&ok) = y.(int) } - { - i := 0 - j := 0 - var ok bool - var x interface{} = i // ERROR "i does not escape" - var y interface{} = j // ERROR "j does not escape" - - sink = x.(int) // ERROR "x.\(int\) escapes to heap" - sink, *(&ok) = y.(int) - } { i := 0 // ERROR "moved to heap: i" j := 0 // ERROR "moved to heap: j" diff --git a/test/escape_iface_nounified.go b/test/escape_iface_nounified.go new file mode 100644 index 0000000000000..1d267bcd185f5 --- /dev/null +++ b/test/escape_iface_nounified.go @@ -0,0 +1,25 @@ +// errorcheck -0 -m -l +//go:build !goexperiment.unified +// +build !goexperiment.unified + +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package escape + +var sink interface{} + +func dotTypeEscape2() { // #13805, #15796 + { + i := 0 + j := 0 + var ok bool + var x interface{} = i // ERROR "i does not escape" + var y interface{} = j // ERROR "j does not escape" + + sink = x.(int) // ERROR "x.\(int\) escapes to heap" + // BAD: should be "y.\(int\) escapes to heap" too + sink, *(&ok) = y.(int) + } +} diff --git a/test/escape_iface_unified.go b/test/escape_iface_unified.go new file mode 100644 index 0000000000000..7ac8e001515d7 --- /dev/null +++ b/test/escape_iface_unified.go @@ -0,0 +1,25 @@ +// errorcheck -0 -m -l +//go:build goexperiment.unified +// +build goexperiment.unified + +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package escape + +var sink interface{} + +func dotTypeEscape2() { // #13805, #15796 + { + i := 0 + j := 0 + var ok bool + var x interface{} = i // ERROR "i does not escape" + var y interface{} = j // ERROR "j does not escape" + + sink = x.(int) // ERROR "x.\(int\) escapes to heap" + // BAD: should be "y.\(int\) escapes to heap" too + sink, *(&ok) = y.(int) + } +}