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 }