OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / go.test / test / chan / select3.go
1 // $G $D/$F.go && $L $F.$A && ./$A.out
2
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Tests verifying the semantics of the select statement
8 // for basic empty/non-empty cases.
9
10 package main
11
12 import "time"
13
14 const always = "function did not"
15 const never = "function did"
16
17
18 func unreachable() {
19         panic("control flow shouldn't reach here")
20 }
21
22
23 // Calls f and verifies that f always/never panics depending on signal.
24 func testPanic(signal string, f func()) {
25         defer func() {
26                 s := never
27                 if recover() != nil {
28                         s = always // f panicked
29                 }
30                 if s != signal {
31                         panic(signal + " panic")
32                 }
33         }()
34         f()
35 }
36
37
38 // Calls f and empirically verifies that f always/never blocks depending on signal.
39 func testBlock(signal string, f func()) {
40         c := make(chan string)
41         go func() {
42                 f()
43                 c <- never // f didn't block
44         }()
45         go func() {
46                 time.Sleep(1e8) // 0.1s seems plenty long
47                 c <- always     // f blocked always
48         }()
49         if <-c != signal {
50                 panic(signal + " block")
51         }
52 }
53
54
55 func main() {
56         const async = 1 // asynchronous channels
57         var nilch chan int
58         closedch := make(chan int)
59         close(closedch)
60
61         // sending/receiving from a nil channel outside a select panics
62         testPanic(always, func() {
63                 nilch <- 7
64         })
65         testPanic(always, func() {
66                 <-nilch
67         })
68
69         // sending/receiving from a nil channel inside a select never panics
70         testPanic(never, func() {
71                 select {
72                 case nilch <- 7:
73                         unreachable()
74                 default:
75                 }
76         })
77         testPanic(never, func() {
78                 select {
79                 case <-nilch:
80                         unreachable()
81                 default:
82                 }
83         })
84
85         // sending to an async channel with free buffer space never blocks
86         testBlock(never, func() {
87                 ch := make(chan int, async)
88                 ch <- 7
89         })
90
91         // receiving (a small number of times) from a closed channel never blocks
92         testBlock(never, func() {
93                 for i := 0; i < 10; i++ {
94                         if <-closedch != 0 {
95                                 panic("expected zero value when reading from closed channel")
96                         }
97                 }
98         })
99
100         // sending (a small number of times) to a closed channel is not specified
101         // but the current implementation doesn't block: test that different
102         // implementations behave the same
103         testBlock(never, func() {
104                 for i := 0; i < 10; i++ {
105                         closedch <- 7
106                 }
107         })
108
109         // receiving from a non-ready channel always blocks
110         testBlock(always, func() {
111                 ch := make(chan int)
112                 <-ch
113         })
114
115         // empty selects always block
116         testBlock(always, func() {
117                 select {
118                 }
119         })
120
121         // selects with only nil channels always block
122         testBlock(always, func() {
123                 select {
124                 case <-nilch:
125                         unreachable()
126                 }
127         })
128         testBlock(always, func() {
129                 select {
130                 case nilch <- 7:
131                         unreachable()
132                 }
133         })
134         testBlock(always, func() {
135                 select {
136                 case <-nilch:
137                         unreachable()
138                 case nilch <- 7:
139                         unreachable()
140                 }
141         })
142
143         // selects with non-ready non-nil channels always block
144         testBlock(always, func() {
145                 ch := make(chan int)
146                 select {
147                 case <-ch:
148                         unreachable()
149                 }
150         })
151
152         // selects with default cases don't block
153         testBlock(never, func() {
154                 select {
155                 default:
156                 }
157         })
158         testBlock(never, func() {
159                 select {
160                 case <-nilch:
161                         unreachable()
162                 default:
163                 }
164         })
165         testBlock(never, func() {
166                 select {
167                 case nilch <- 7:
168                         unreachable()
169                 default:
170                 }
171         })
172
173         // selects with ready channels don't block
174         testBlock(never, func() {
175                 ch := make(chan int, async)
176                 select {
177                 case ch <- 7:
178                 default:
179                         unreachable()
180                 }
181         })
182         testBlock(never, func() {
183                 ch := make(chan int, async)
184                 ch <- 7
185                 select {
186                 case <-ch:
187                 default:
188                         unreachable()
189                 }
190         })
191
192         // selects with closed channels don't block
193         testBlock(never, func() {
194                 select {
195                 case <-closedch:
196                 }
197         })
198         testBlock(never, func() {
199                 select {
200                 case closedch <- 7:
201                 }
202         })
203 }