summaryrefslogtreecommitdiffstats
path: root/test/fixedbugs/issue27695.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/fixedbugs/issue27695.go')
-rw-r--r--test/fixedbugs/issue27695.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/test/fixedbugs/issue27695.go b/test/fixedbugs/issue27695.go
new file mode 100644
index 0000000..8bd4939
--- /dev/null
+++ b/test/fixedbugs/issue27695.go
@@ -0,0 +1,62 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure return values are always scanned, when
+// calling methods (+functions, TODO) with reflect.
+
+package main
+
+import (
+ "reflect"
+ "runtime/debug"
+ "sync"
+)
+
+func main() {
+ debug.SetGCPercent(1) // run GC frequently
+ var wg sync.WaitGroup
+ for i := 0; i < 20; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for i := 0; i < 2000; i++ {
+ _test()
+ }
+ }()
+ }
+ wg.Wait()
+}
+
+type Stt struct {
+ Data interface{}
+}
+
+type My struct {
+ b byte
+}
+
+func (this *My) Run(rawData []byte) (Stt, error) {
+ var data string = "hello"
+ stt := Stt{
+ Data: data,
+ }
+ return stt, nil
+}
+
+func _test() (interface{}, error) {
+ f := reflect.ValueOf(&My{}).MethodByName("Run")
+ if method, ok := f.Interface().(func([]byte) (Stt, error)); ok {
+ s, e := method(nil)
+ // The bug in issue27695 happens here, during the return
+ // from the above call (at the end of reflect.callMethod
+ // when preparing to return). The result value that
+ // is assigned to s was not being scanned if GC happens
+ // to occur there.
+ i := interface{}(s)
+ return i, e
+ }
+ return nil, nil
+}