aboutsummaryrefslogtreecommitdiff
path: root/src/reflect/all_test.go
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2021-11-11 19:58:23 -0500
committerCherry Mui <cherryyz@google.com>2021-11-12 14:56:58 +0000
commit23adc139bf1c0c099dd075da076f5a1f3ac700d4 (patch)
tree83e02a244a5ad49eb1461ec1a5d9a6a9806a54f3 /src/reflect/all_test.go
parente9f0381a807d1797e0b5969a29f4a3666a73c9e3 (diff)
downloadgo-23adc139bf1c0c099dd075da076f5a1f3ac700d4.tar.gz
go-23adc139bf1c0c099dd075da076f5a1f3ac700d4.zip
reflect: keep pointer in aggregate-typed args live in Call
When register ABI is used, reflect.Value.Call prepares the call arguments in a memory representation of the argument registers. It has special handling to keep the pointers in arguments live. Currently, this handles pointer-typed arguments. But when an argument is an aggregate-type that contains pointers and passed in registers, it currently doesn't keep the pointers live. Do so in this CL. May fix #49363. Change-Id: Ic6a0c5fdf9375ef02f7c03fbe9345e2e98c9353d Reviewed-on: https://go-review.googlesource.com/c/go/+/363358 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/reflect/all_test.go')
-rw-r--r--src/reflect/all_test.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index acc09962a0..8c51d8ec26 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -6478,6 +6478,29 @@ func TestCallMethodJump(t *testing.T) {
*CallGC = false
}
+func TestCallArgLive(t *testing.T) {
+ type T struct{ X, Y *string } // pointerful aggregate
+
+ F := func(t T) { *t.X = "ok" }
+
+ // In reflect.Value.Call, trigger a garbage collection in reflect.call
+ // between marshaling argument and the actual call.
+ *CallGC = true
+
+ x := new(string)
+ runtime.SetFinalizer(x, func(p *string) {
+ if *p != "ok" {
+ t.Errorf("x dead prematurely")
+ }
+ })
+ v := T{x, nil}
+
+ ValueOf(F).Call([]Value{ValueOf(v)})
+
+ // Stop garbage collecting during reflect.call.
+ *CallGC = false
+}
+
func TestMakeFuncStackCopy(t *testing.T) {
target := func(in []Value) []Value {
runtime.GC()