diff options
Diffstat (limited to '')
-rw-r--r-- | test/fixedbugs/issue59680.go | 100 |
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{}{} + } +} |