github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/test/fixedbugs/issue27695.go (about) 1 // run 2 3 // Copyright 2018 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Make sure return values are always scanned, when 8 // calling methods (+functions, TODO) with reflect. 9 10 package main 11 12 import ( 13 "reflect" 14 "runtime/debug" 15 "sync" 16 ) 17 18 func main() { 19 debug.SetGCPercent(1) // run GC frequently 20 var wg sync.WaitGroup 21 for i := 0; i < 20; i++ { 22 wg.Add(1) 23 go func() { 24 defer wg.Done() 25 for i := 0; i < 2000; i++ { 26 _test() 27 } 28 }() 29 } 30 wg.Wait() 31 } 32 33 type Stt struct { 34 Data interface{} 35 } 36 37 type My struct { 38 b byte 39 } 40 41 func (this *My) Run(rawData []byte) (Stt, error) { 42 var data string = "hello" 43 stt := Stt{ 44 Data: data, 45 } 46 return stt, nil 47 } 48 49 func _test() (interface{}, error) { 50 f := reflect.ValueOf(&My{}).MethodByName("Run") 51 if method, ok := f.Interface().(func([]byte) (Stt, error)); ok { 52 s, e := method(nil) 53 // The bug in issue27695 happens here, during the return 54 // from the above call (at the end of reflect.callMethod 55 // when preparing to return). The result value that 56 // is assigned to s was not being scanned if GC happens 57 // to occur there. 58 i := interface{}(s) 59 return i, e 60 } 61 return nil, nil 62 }