diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2017-01-23 22:18:42 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2017-01-23 22:18:42 +0000 |
commit | c25edd44a04672573946138da9c8fdc8c0eef5fd (patch) | |
tree | 843ee0b88a49a9a81be51f8853f88eb3c11256b1 /libgo/go/reflect | |
parent | 28826a66fb457b6655d66a40638a759617aa8673 (diff) |
libgo: update to go1.8rc2
Fix a bug in the generation of the hash value in reflect.FuncOf.
The merge script missed a bunch of testdata files over the years.
Copy them over.
Reviewed-on: https://go-review.googlesource.com/35570
From-SVN: r244835
Diffstat (limited to 'libgo/go/reflect')
-rw-r--r-- | libgo/go/reflect/all_test.go | 68 | ||||
-rw-r--r-- | libgo/go/reflect/type.go | 3 |
2 files changed, 70 insertions, 1 deletions
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index f51e95fd734..6b143df00e1 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -26,6 +26,8 @@ import ( "unsafe" ) +var sink interface{} + func TestBool(t *testing.T) { v := ValueOf(true) if v.Bool() != true { @@ -5348,6 +5350,72 @@ func TestCallGC(t *testing.T) { f2("four", "five5", "six666", "seven77", "eight888") } +// Issue 18635 (function version). +func TestKeepFuncLive(t *testing.T) { + // Test that we keep makeFuncImpl live as long as it is + // referenced on the stack. + typ := TypeOf(func(i int) {}) + var f, g func(in []Value) []Value + f = func(in []Value) []Value { + clobber() + i := int(in[0].Int()) + if i > 0 { + // We can't use Value.Call here because + // runtime.call* will keep the makeFuncImpl + // alive. However, by converting it to an + // interface value and calling that, + // reflect.callReflect is the only thing that + // can keep the makeFuncImpl live. + // + // Alternate between f and g so that if we do + // reuse the memory prematurely it's more + // likely to get obviously corrupted. + MakeFunc(typ, g).Interface().(func(i int))(i - 1) + } + return nil + } + g = func(in []Value) []Value { + clobber() + i := int(in[0].Int()) + MakeFunc(typ, f).Interface().(func(i int))(i) + return nil + } + MakeFunc(typ, f).Call([]Value{ValueOf(10)}) +} + +// Issue 18635 (method version). +type KeepMethodLive struct{} + +func (k KeepMethodLive) Method1(i int) { + clobber() + if i > 0 { + ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1) + } +} + +func (k KeepMethodLive) Method2(i int) { + clobber() + ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i) +} + +func TestKeepMethodLive(t *testing.T) { + // Test that we keep methodValue live as long as it is + // referenced on the stack. + KeepMethodLive{}.Method1(10) +} + +// clobber tries to clobber unreachable memory. +func clobber() { + runtime.GC() + for i := 1; i < 32; i++ { + for j := 0; j < 10; j++ { + obj := make([]*byte, i) + sink = obj + } + } + runtime.GC() +} + type funcLayoutTest struct { rcvr, t Type size, argsize, retOffset uintptr diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 07a355d5e41..29d89f7176d 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -1677,7 +1677,7 @@ func FuncOf(in, out []Type, variadic bool) Type { *ft = *prototype // Build a hash and minimally populate ft. - var hash uint32 = 8 + var hash uint32 var fin, fout []*rtype shift := uint(1) for _, in := range in { @@ -1697,6 +1697,7 @@ func FuncOf(in, out []Type, variadic bool) Type { hash++ } hash <<= 4 + hash += 8 ft.hash = hash ft.in = fin ft.out = fout |