diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-25 05:14:57 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-25 05:14:57 +0000 |
commit | fe052134f692c852e092a94917dfdec7b13612c0 (patch) | |
tree | ace019ab5161d52cce663b4c7408d746727efc5c /gcc/testsuite/go.test | |
parent | e533b2a4c9ce8ee4fd207728dba3a9e2ffc5374a (diff) | |
download | gcc-fe052134f692c852e092a94917dfdec7b13612c0.tar.gz |
Remove closed function. Fix tuple receive in select.
From-SVN: r171440
Diffstat (limited to 'gcc/testsuite/go.test')
-rw-r--r-- | gcc/testsuite/go.test/test/chan/doubleselect.go | 36 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/chan/perm.go | 15 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/chan/select3.go | 27 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/closedchan.go | 157 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/named1.go | 9 |
5 files changed, 160 insertions, 84 deletions
diff --git a/gcc/testsuite/go.test/test/chan/doubleselect.go b/gcc/testsuite/go.test/test/chan/doubleselect.go index 592d2f54a43..3c7412ed6ab 100644 --- a/gcc/testsuite/go.test/test/chan/doubleselect.go +++ b/gcc/testsuite/go.test/test/chan/doubleselect.go @@ -21,6 +21,8 @@ var iterations *int = flag.Int("n", 100000, "number of iterations") func sender(n int, c1, c2, c3, c4 chan<- int) { defer close(c1) defer close(c2) + defer close(c3) + defer close(c4) for i := 0; i < n; i++ { select { @@ -35,26 +37,18 @@ func sender(n int, c1, c2, c3, c4 chan<- int) { // mux receives the values from sender and forwards them onto another channel. // It would be simplier to just have sender's four cases all be the same // channel, but this doesn't actually trigger the bug. -func mux(out chan<- int, in <-chan int) { - for { - v := <-in - if closed(in) { - close(out) - break - } +func mux(out chan<- int, in <-chan int, done chan<- bool) { + for v := range in { out <- v } + done <- true } // recver gets a steam of values from the four mux's and checks for duplicates. func recver(in <-chan int) { seen := make(map[int]bool) - for { - v := <-in - if closed(in) { - break - } + for v := range in { if _, ok := seen[v]; ok { println("got duplicate value: ", v) panic("fail") @@ -70,15 +64,23 @@ func main() { c2 := make(chan int) c3 := make(chan int) c4 := make(chan int) + done := make(chan bool) cmux := make(chan int) go sender(*iterations, c1, c2, c3, c4) - go mux(cmux, c1) - go mux(cmux, c2) - go mux(cmux, c3) - go mux(cmux, c4) + go mux(cmux, c1, done) + go mux(cmux, c2, done) + go mux(cmux, c3, done) + go mux(cmux, c4, done) + go func() { + <-done + <-done + <-done + <-done + close(cmux) + }() // We keep the recver because it might catch more bugs in the future. // However, the result of the bug linked to at the top is that we'll - // end up panicing with: "throw: bad g->status in ready". + // end up panicking with: "throw: bad g->status in ready". recver(cmux) print("PASS\n") } diff --git a/gcc/testsuite/go.test/test/chan/perm.go b/gcc/testsuite/go.test/test/chan/perm.go index c725829d132..038ff94e369 100644 --- a/gcc/testsuite/go.test/test/chan/perm.go +++ b/gcc/testsuite/go.test/test/chan/perm.go @@ -22,21 +22,18 @@ func main() { c <- 0 // ok <-c // ok - //TODO(rsc): uncomment when this syntax is valid for receive+check closed - // x, ok := <-c // ok - // _, _ = x, ok + x, ok := <-c // ok + _, _ = x, ok cr <- 0 // ERROR "send" <-cr // ok - //TODO(rsc): uncomment when this syntax is valid for receive+check closed - // x, ok = <-cr // ok - // _, _ = x, ok + x, ok = <-cr // ok + _, _ = x, ok cs <- 0 // ok <-cs // ERROR "receive" - ////TODO(rsc): uncomment when this syntax is valid for receive+check closed - //// x, ok = <-cs // ERROR "receive" - //// _, _ = x, ok + x, ok = <-cs // ERROR "receive" + _, _ = x, ok select { case c <- 0: // ok diff --git a/gcc/testsuite/go.test/test/chan/select3.go b/gcc/testsuite/go.test/test/chan/select3.go index 9877b12a98c..b4e8f8e4bf9 100644 --- a/gcc/testsuite/go.test/test/chan/select3.go +++ b/gcc/testsuite/go.test/test/chan/select3.go @@ -88,12 +88,16 @@ func main() { ch <- 7 }) - // receiving (a small number of times) from a closed channel never blocks + // receiving from a closed channel never blocks testBlock(never, func() { for i := 0; i < 10; i++ { if <-closedch != 0 { panic("expected zero value when reading from closed channel") } + if x, ok := <-closedch; x != 0 || ok { + println("closedch:", x, ok) + panic("expected 0, false from closed channel") + } } }) @@ -191,9 +195,30 @@ func main() { case <-closedch: } }) + testBlock(never, func() { + select { + case x := <-closedch: + _ = x + } + }) + testBlock(never, func() { + select { + case x, ok := <-closedch: + _, _ = x, ok + } + }) testPanic(always, func() { select { case closedch <- 7: } }) + + // select should not get confused if it sees itself + testBlock(always, func() { + c := make(chan int) + select { + case c <- 1: + case <-c: + } + }) } diff --git a/gcc/testsuite/go.test/test/closedchan.go b/gcc/testsuite/go.test/test/closedchan.go index 46d9d0f5d21..95314b3345e 100644 --- a/gcc/testsuite/go.test/test/closedchan.go +++ b/gcc/testsuite/go.test/test/closedchan.go @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Test close(c), closed(c). +// Test close(c), receive of closed channel. // // TODO(rsc): Doesn't check behavior of close(c) when there // are blocked senders/receivers. @@ -14,10 +14,11 @@ package main type Chan interface { Send(int) Nbsend(int) bool - Recv() int + Recv() (int) Nbrecv() (int, bool) + Recv2() (int, bool) + Nbrecv2() (int, bool, bool) Close() - Closed() bool Impl() string } @@ -52,12 +53,23 @@ func (c XChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c XChan) Close() { - close(c) +func (c XChan) Recv2() (int, bool) { + x, ok := <-c + return x, ok +} + +func (c XChan) Nbrecv2() (int, bool, bool) { + select { + case x, ok := <-c: + return x, ok, true + default: + return 0, false, false + } + panic("nbrecv2") } -func (c XChan) Closed() bool { - return closed(c) +func (c XChan) Close() { + close(c) } func (c XChan) Impl() string { @@ -101,12 +113,26 @@ func (c SChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c SChan) Close() { - close(c) +func (c SChan) Recv2() (int, bool) { + select { + case x, ok := <-c: + return x, ok + } + panic("recv") } -func (c SChan) Closed() bool { - return closed(c) +func (c SChan) Nbrecv2() (int, bool, bool) { + select { + default: + return 0, false, false + case x, ok := <-c: + return x, ok, true + } + panic("nbrecv") +} + +func (c SChan) Close() { + close(c) } func (c SChan) Impl() string { @@ -156,12 +182,28 @@ func (c SSChan) Nbrecv() (int, bool) { panic("nbrecv") } -func (c SSChan) Close() { - close(c) +func (c SSChan) Recv2() (int, bool) { + select { + case <-dummy: + case x, ok := <-c: + return x, ok + } + panic("recv") } -func (c SSChan) Closed() bool { - return closed(c) +func (c SSChan) Nbrecv2() (int, bool, bool) { + select { + case <-dummy: + default: + return 0, false, false + case x, ok := <-c: + return x, ok, true + } + panic("nbrecv") +} + +func (c SSChan) Close() { + close(c) } func (c SSChan) Impl() string { @@ -179,29 +221,23 @@ func shouldPanic(f func()) { } func test1(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("test1: Closed before Recv zero:", c.Impl()) - } - for i := 0; i < 3; i++ { // recv a close signal (a zero value) if x := c.Recv(); x != 0 { - println("test1: recv on closed got non-zero:", x, c.Impl()) + println("test1: recv on closed:", x, c.Impl()) } - - // should now be closed. - if !c.Closed() { - println("test1: not closed after recv zero", c.Impl()) + if x, ok := c.Recv2(); x != 0 || ok { + println("test1: recv2 on closed:", x, ok, c.Impl()) } - // should work with ,ok: received a value without blocking, so ok == true. - x, ok := c.Nbrecv() - if !ok { - println("test1: recv on closed got not ok", c.Impl()) + // should work with select: received a value without blocking, so selected == true. + x, selected := c.Nbrecv() + if x != 0 || !selected { + println("test1: recv on closed nb:", x, selected, c.Impl()) } - if x != 0 { - println("test1: recv ,ok on closed got non-zero:", x, c.Impl()) + x, ok, selected := c.Nbrecv2() + if x != 0 || ok || !selected { + println("test1: recv2 on closed nb:", x, ok, selected, c.Impl()) } } @@ -221,11 +257,6 @@ func test1(c Chan) { } func testasync1(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("testasync1: Closed before Recv zero:", c.Impl()) - } - // should be able to get the last value via Recv if x := c.Recv(); x != 1 { println("testasync1: Recv did not get 1:", x, c.Impl()) @@ -235,19 +266,31 @@ func testasync1(c Chan) { } func testasync2(c Chan) { - // not closed until the close signal (a zero value) has been received. - if c.Closed() { - println("testasync2: Closed before Recv zero:", c.Impl()) + // should be able to get the last value via Recv2 + if x, ok := c.Recv2(); x != 1 || !ok { + println("testasync1: Recv did not get 1, true:", x, ok, c.Impl()) } + test1(c) +} + +func testasync3(c Chan) { // should be able to get the last value via Nbrecv - if x, ok := c.Nbrecv(); !ok || x != 1 { - println("testasync2: Nbrecv did not get 1, true:", x, ok, c.Impl()) + if x, selected := c.Nbrecv(); x != 1 || !selected { + println("testasync2: Nbrecv did not get 1, true:", x, selected, c.Impl()) } test1(c) } +func testasync4(c Chan) { + // should be able to get the last value via Nbrecv2 + if x, ok, selected := c.Nbrecv2(); x != 1 || !ok || !selected { + println("testasync2: Nbrecv did not get 1, true, true:", x, ok, selected, c.Impl()) + } + test1(c) +} + func closedsync() chan int { c := make(chan int) close(c) @@ -261,15 +304,27 @@ func closedasync() chan int { return c } +var mks = []func(chan int) Chan { + func(c chan int) Chan { return XChan(c) }, + func(c chan int) Chan { return SChan(c) }, + func(c chan int) Chan { return SSChan(c) }, +} + +var testcloseds = []func(Chan) { + testasync1, + testasync2, + testasync3, + testasync4, +} + func main() { - test1(XChan(closedsync())) - test1(SChan(closedsync())) - test1(SSChan(closedsync())) - - testasync1(XChan(closedasync())) - testasync1(SChan(closedasync())) - testasync1(SSChan(closedasync())) - testasync2(XChan(closedasync())) - testasync2(SChan(closedasync())) - testasync2(SSChan(closedasync())) + for _, mk := range mks { + test1(mk(closedsync())) + } + + for _, testclosed := range testcloseds { + for _, mk := range mks { + testclosed(mk(closedasync())) + } + } } diff --git a/gcc/testsuite/go.test/test/named1.go b/gcc/testsuite/go.test/test/named1.go index 1776313f05c..7e7aab9c1d8 100644 --- a/gcc/testsuite/go.test/test/named1.go +++ b/gcc/testsuite/go.test/test/named1.go @@ -43,10 +43,6 @@ func main() { _, b = m[2] // ERROR "cannot .* bool.*type Bool" m[2] = 1, b // ERROR "cannot use.*type Bool.*as type bool" - ////TODO(rsc): uncomment when this syntax is valid for receive+check closed - //// _, b = <-c // ERROR "cannot .* bool.*type Bool" - //// _ = b - var inter interface{} _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool" _ = b @@ -57,8 +53,9 @@ func main() { _, b = minter.(Map) // ERROR "cannot .* bool.*type Bool" _ = b - asBool(closed(c)) // ERROR "cannot use.*type bool.*as type Bool" - b = closed(c) // ERROR "cannot use.*type bool.*type Bool" + _, bb := <-c + asBool(bb) // ERROR "cannot use.*type bool.*as type Bool" + _, b = <-c // ERROR "cannot .* bool.*type Bool" _ = b asString(String(slice)) // ERROR "cannot .*type Slice.*type String" |