summaryrefslogtreecommitdiffstats
path: root/test/fixedbugs/issue59680.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/fixedbugs/issue59680.go')
-rw-r--r--test/fixedbugs/issue59680.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/test/fixedbugs/issue59680.go b/test/fixedbugs/issue59680.go
new file mode 100644
index 0000000..d21f61f
--- /dev/null
+++ b/test/fixedbugs/issue59680.go
@@ -0,0 +1,100 @@
+// run
+
+// Copyright 2023 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.
+
+package main
+
+import (
+ "sync"
+ "time"
+)
+
+type B struct {
+ pid int
+ f func() (uint64, error)
+ wg sync.WaitGroup
+ v uint64
+}
+
+func newB(pid int) *B {
+ return &B{
+ pid: pid,
+ }
+}
+
+//go:noinline
+func Sq(i int) uint64 {
+ S++
+ return uint64(i * i)
+}
+
+type RO func(*B)
+
+var ROSL = []RO{
+ Bad(),
+}
+
+func Bad() RO {
+ return func(b *B) {
+ b.f = func() (uint64, error) {
+ return Sq(b.pid), nil
+ }
+ }
+}
+
+func (b *B) startit() chan<- struct{} {
+ stop := make(chan struct{})
+ b.wg.Add(1)
+ go func() {
+ defer b.wg.Done()
+ var v uint64
+ for {
+ select {
+ case <-stop:
+ b.v = v
+ return
+ case <-time.After(1 * time.Millisecond):
+ r, err := b.f()
+ if err != nil {
+ panic("bad")
+ }
+ v = r
+ }
+ }
+ }()
+ return stop
+}
+
+var S, G int
+
+//go:noinline
+func rec(x int) int {
+ if x == 0 {
+ return 9
+ }
+ return rec(x-1) + 1
+}
+
+//go:noinline
+func recur(x int) {
+ for i := 0; i < x; i++ {
+ G = rec(i)
+ }
+}
+
+func main() {
+ b := newB(17)
+ for _, opt := range ROSL {
+ opt(b)
+ }
+ stop := b.startit()
+
+ // see if we can get some stack growth/moving
+ recur(10101)
+
+ if stop != nil {
+ stop <- struct{}{}
+ }
+}