I realized that in the amd64 implementation of MakeFunc I forgot that
it's not OK to just take the address of a value on the stack, since the
function might hang onto the address.  The value needs to be copied onto
the heap first.  This patch implements that.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline and 4.8
branch.

Ian

diff -r cec0db170d82 libgo/go/reflect/makefuncgo_amd64.go
--- a/libgo/go/reflect/makefuncgo_amd64.go	Fri Sep 27 14:31:06 2013 -0700
+++ b/libgo/go/reflect/makefuncgo_amd64.go	Fri Sep 27 15:11:00 2013 -0700
@@ -431,8 +431,14 @@
 func amd64Memarg(in []Value, ap uintptr, rt *rtype) ([]Value, uintptr) {
 	ap = align(ap, ptrSize)
 	ap = align(ap, uintptr(rt.align))
-	p := Value{rt, unsafe.Pointer(ap), flag(rt.Kind()<<flagKindShift) | flagIndir}
-	in = append(in, p)
+
+	// We have to copy the argument onto the heap in case the
+	// function hangs onto the reflect.Value we pass it.
+	p := unsafe_New(rt)
+	memmove(p, unsafe.Pointer(ap), rt.size)
+
+	v := Value{rt, p, flag(rt.Kind()<<flagKindShift) | flagIndir}
+	in = append(in, v)
 	ap += rt.size
 	return in, ap
 }

Reply via email to