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.
This commit is contained in:
Marc Vertes
2022-09-12 15:32:08 +02:00
committed by GitHub
parent 79747f3d6f
commit 2e8808317f
4 changed files with 50 additions and 5 deletions

41
_test/issue-1442.go Normal file
View File

@@ -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:
//

View File

@@ -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"
}()

View File

@@ -6,8 +6,8 @@ import (
)
const (
period = 100 * time.Millisecond
precision = 7 * time.Millisecond
period = 300 * time.Millisecond
precision = 30 * time.Millisecond
)
func main() {

View File

@@ -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]; {