Skip to content

Commit

Permalink
fix: correct handling of select comm clause with empty body
Browse files Browse the repository at this point in the history
Fixes #887.
  • Loading branch information
mvertes authored Oct 13, 2020
1 parent f362237 commit 9491e58
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 27 deletions.
23 changes: 23 additions & 0 deletions _test/select14.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

type T struct {
c1 chan string
c2 chan string
}

func main() {
t := &T{}
t.c2 = make(chan string)

go func(c chan string) { c <- "done" }(t.c2)

select {
case msg := <-t.c1:
println("received from c1:", msg)
case <-t.c2:
}
println("Bye")
}

// Output:
// Bye
55 changes: 28 additions & 27 deletions interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2970,33 +2970,34 @@ func _select(n *node) {
// The comm clause is an empty default, exit select.
cases[i].Dir = reflect.SelectDefault
clause[i] = func(*frame) bltn { return next }
} else {
switch c0 := n.child[i].child[0]; {
case len(n.child[i].child) > 1:
// The comm clause contains a channel operation and a clause body.
clause[i] = getExec(n.child[i].child[1].start)
chans[i], assigned[i], ok[i], cases[i].Dir = clauseChanDir(n.child[i])
chanValues[i] = genValue(chans[i])
if assigned[i] != nil {
assignedValues[i] = genValue(assigned[i])
}
if ok[i] != nil {
okValues[i] = genValue(ok[i])
}
case c0.kind == exprStmt && len(c0.child) == 1 && c0.child[0].action == aRecv:
// The comm clause has an empty body clause after channel receive.
chanValues[i] = genValue(c0.child[0].child[0])
cases[i].Dir = reflect.SelectRecv
case c0.kind == sendStmt:
// The comm clause as an empty body clause after channel send.
chanValues[i] = genValue(c0.child[0])
cases[i].Dir = reflect.SelectSend
assignedValues[i] = genValue(c0.child[1])
default:
// The comm clause has a default clause.
clause[i] = getExec(c0.start)
cases[i].Dir = reflect.SelectDefault
}
continue
}
switch c0 := n.child[i].child[0]; {
case len(n.child[i].child) > 1:
// The comm clause contains a channel operation and a clause body.
clause[i] = getExec(n.child[i].child[1].start)
chans[i], assigned[i], ok[i], cases[i].Dir = clauseChanDir(n.child[i])
chanValues[i] = genValue(chans[i])
if assigned[i] != nil {
assignedValues[i] = genValue(assigned[i])
}
if ok[i] != nil {
okValues[i] = genValue(ok[i])
}
case c0.kind == exprStmt && len(c0.child) == 1 && c0.child[0].action == aRecv:
// The comm clause has an empty body clause after channel receive.
chanValues[i] = genValue(c0.child[0].child[0])
cases[i].Dir = reflect.SelectRecv
clause[i] = func(*frame) bltn { return next }
case c0.kind == sendStmt:
// The comm clause as an empty body clause after channel send.
chanValues[i] = genValue(c0.child[0])
cases[i].Dir = reflect.SelectSend
assignedValues[i] = genValue(c0.child[1])
default:
// The comm clause has a default clause.
clause[i] = getExec(c0.start)
cases[i].Dir = reflect.SelectDefault
}
}

Expand Down

0 comments on commit 9491e58

Please sign in to comment.