From 2e8808317f30a600d36f1e1adb09e7a05dd6c315 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 12 Sep 2022 15:32:08 +0200 Subject: [PATCH] interp: fix default comm clause in select Do not attempt to init a non-existent channel setting when in default communication clause in select. Fixes #1442. --- _test/issue-1442.go | 41 +++++++++++++++++++++++++++++++++++++++++ _test/select1.go | 4 ++-- _test/select14.go | 4 ++-- interp/cfg.go | 6 +++++- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 _test/issue-1442.go diff --git a/_test/issue-1442.go b/_test/issue-1442.go new file mode 100644 index 000000000..df0375430 --- /dev/null +++ b/_test/issue-1442.go @@ -0,0 +1,41 @@ +package main + +import ( + "context" +) + +func main() { + ctx, _ := context.WithCancel(context.Background()) + ch := make(chan string, 20) + defer close(ch) + + go func(ctx context.Context, ch <-chan string) { + for { + select { + case <-ctx.Done(): + return + case tmp := <-ch: + _ = tmp + } + } + }(ctx, ch) + + for _, i := range "abcdef" { + for _, j := range "0123456789" { + // i, j := "a", "0" + for _, k := range "ABCDEF" { + select { + case <-ctx.Done(): + return + default: + tmp := string(i) + string(j) + string(k) + ch <- tmp + } + } + } + } + return +} + +// Output: +// diff --git a/_test/select1.go b/_test/select1.go index 57983d2f4..af910833c 100644 --- a/_test/select1.go +++ b/_test/select1.go @@ -10,11 +10,11 @@ func main() { c2 := make(chan string) go func() { - time.Sleep(1e7) + time.Sleep(1e8) c1 <- "one" }() go func() { - time.Sleep(2e7) + time.Sleep(2e8) c2 <- "two" }() diff --git a/_test/select14.go b/_test/select14.go index e90b24949..99c244b95 100644 --- a/_test/select14.go +++ b/_test/select14.go @@ -6,8 +6,8 @@ import ( ) const ( - period = 100 * time.Millisecond - precision = 7 * time.Millisecond + period = 300 * time.Millisecond + precision = 30 * time.Millisecond ) func main() { diff --git a/interp/cfg.go b/interp/cfg.go index 73721ef1f..5b9037e75 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -1920,9 +1920,13 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string wireChild(n) // Move action to block statement, so select node can be an exit point. n.child[0].gen = _select - // Chain channel init actions in commClauses prior to invoke select. + // Chain channel init actions in commClauses prior to invoking select. var cur *node for _, c := range n.child[0].child { + if c.kind == commClauseDefault { + // No channel init in this case. + continue + } var an, pn *node // channel init action nodes if len(c.child) > 0 { switch c0 := c.child[0]; {