summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-08-03 01:07:57 -0700
committerRuss Cox <rsc@golang.org>2010-08-03 01:07:57 -0700
commit545d7a95311de475edb11ce92b848ed28e451c49 (patch)
treec66b921451129667a006fdf788c07681e7cf0180
parent63796575378823bb31fbe99079fc9438958b8bca (diff)
downloadgo-545d7a95311de475edb11ce92b848ed28e451c49.tar.gz
gc: empty select
R=ken2 CC=golang-dev http://codereview.appspot.com/1871057
-rw-r--r--src/cmd/gc/select.c4
-rw-r--r--src/pkg/runtime/chan.c8
-rw-r--r--test/chan/select3.go57
3 files changed, 32 insertions, 37 deletions
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c
index 9cba01fa5..2fa435316 100644
--- a/src/cmd/gc/select.c
+++ b/src/cmd/gc/select.c
@@ -68,8 +68,6 @@ typecheckselect(Node *sel)
typechecklist(ncase->nbody, Etop);
}
sel->xoffset = count;
- if(count == 0)
- yyerror("empty select");
lineno = lno;
}
@@ -91,7 +89,7 @@ walkselect(Node *sel)
typecheck(&r, Etop);
init = list(init, r);
- if(sel->list == nil)
+ if(sel->list == nil && sel->xoffset != 0)
fatal("double walkselect"); // already rewrote
// register cases
diff --git a/src/pkg/runtime/chan.c b/src/pkg/runtime/chan.c
index 9e88e824a..16c02e8e7 100644
--- a/src/pkg/runtime/chan.c
+++ b/src/pkg/runtime/chan.c
@@ -631,9 +631,11 @@ void
printf("select: sel=%p\n", sel);
if(sel->ncase < 2) {
- if(sel->ncase < 1)
- throw("select: no cases");
- // make special case of one.
+ if(sel->ncase < 1) {
+ g->status = Gwaiting; // forever
+ gosched();
+ }
+ // TODO: make special case of one.
}
// select a (relative) prime
diff --git a/test/chan/select3.go b/test/chan/select3.go
index d4f7ebcec..a1a2ef50b 100644
--- a/test/chan/select3.go
+++ b/test/chan/select3.go
@@ -112,38 +112,33 @@ func main() {
<-ch
})
- // TODO(gri) remove this if once 6g accepts empty selects
- enabled := false
- if enabled {
- // empty selects always block
- testBlock(always, func() {
- select {
- case <-make(chan int): // remove this once 6g accepts empty selects
- }
- })
+ // empty selects always block
+ testBlock(always, func() {
+ select {
+ }
+ })
- // selects with only nil channels always block
- testBlock(always, func() {
- select {
- case <-nilch:
- unreachable()
- }
- })
- testBlock(always, func() {
- select {
- case nilch <- 7:
- unreachable()
- }
- })
- testBlock(always, func() {
- select {
- case <-nilch:
- unreachable()
- case nilch <- 7:
- unreachable()
- }
- })
- }
+ // selects with only nil channels always block
+ testBlock(always, func() {
+ select {
+ case <-nilch:
+ unreachable()
+ }
+ })
+ testBlock(always, func() {
+ select {
+ case nilch <- 7:
+ unreachable()
+ }
+ })
+ testBlock(always, func() {
+ select {
+ case <-nilch:
+ unreachable()
+ case nilch <- 7:
+ unreachable()
+ }
+ })
// selects with non-ready non-nil channels always block
testBlock(always, func() {