mirror of
https://github.com/golang/go.git
synced 2025-05-08 09:03:04 +00:00
The previous code assumed that each channel item contained one field. + regression test. R=crawshaw CC=golang-dev https://golang.org/cl/25480044
119 lines
2.6 KiB
Go
119 lines
2.6 KiB
Go
// +build ignore
|
|
|
|
package main
|
|
|
|
func incr(x int) int { return x + 1 }
|
|
|
|
func decr(x int) int { return x - 1 }
|
|
|
|
var unknown bool // defeat dead-code elimination
|
|
|
|
func chan1() {
|
|
chA := make(chan func(int) int, 0) // @line c1makeA
|
|
chB := make(chan func(int) int, 0) // @line c1makeB
|
|
chA <- incr
|
|
chB <- decr
|
|
chB <- func(int) int { return 1 }
|
|
|
|
print(chA) // @pointsto makechan@c1makeA:13
|
|
print(<-chA) // @pointsto main.incr
|
|
|
|
print(chB) // @pointsto makechan@c1makeB:13
|
|
print(<-chB) // @pointsto main.decr | func@16.9
|
|
}
|
|
|
|
func chan2() {
|
|
chA := make(chan func(int) int, 0) // @line c2makeA
|
|
chB := make(chan func(int) int, 0) // @line c2makeB
|
|
chA <- incr
|
|
chB <- decr
|
|
chB <- func(int) int { return 1 }
|
|
|
|
// Channels flow together.
|
|
// Labelsets remain distinct but elements are merged.
|
|
chAB := chA
|
|
if unknown {
|
|
chAB = chB
|
|
}
|
|
|
|
print(chA) // @pointsto makechan@c2makeA:13
|
|
print(<-chA) // @pointsto main.incr
|
|
|
|
print(chB) // @pointsto makechan@c2makeB:13
|
|
print(<-chB) // @pointsto main.decr | func@30.9
|
|
|
|
print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13
|
|
print(<-chAB) // @pointsto main.incr | main.decr | func@30.9
|
|
|
|
(<-chA)(3)
|
|
}
|
|
|
|
// @calls main.chan2 -> main.incr
|
|
|
|
func chan3() {
|
|
chA := make(chan func(int) int, 0) // @line c3makeA
|
|
chB := make(chan func(int) int, 0) // @line c3makeB
|
|
chA <- incr
|
|
chB <- decr
|
|
chB <- func(int) int { return 1 }
|
|
print(chA) // @pointsto makechan@c3makeA:13
|
|
print(<-chA) // @pointsto main.incr
|
|
print(chB) // @pointsto makechan@c3makeB:13
|
|
print(<-chB) // @pointsto main.decr | func@58.9
|
|
|
|
(<-chA)(3)
|
|
}
|
|
|
|
// @calls main.chan3 -> main.incr
|
|
|
|
func chan4() {
|
|
chA := make(chan func(int) int, 0) // @line c4makeA
|
|
chB := make(chan func(int) int, 0) // @line c4makeB
|
|
|
|
select {
|
|
case chA <- incr:
|
|
case chB <- decr:
|
|
case a := <-chA:
|
|
print(a) // @pointsto main.incr
|
|
case b := <-chB:
|
|
print(b) // @pointsto main.decr
|
|
default:
|
|
print(chA) // @pointsto makechan@c4makeA:13
|
|
print(chB) // @pointsto makechan@c4makeB:13
|
|
}
|
|
|
|
for k := range chA {
|
|
print(k) // @pointsto main.incr
|
|
}
|
|
// Exercise constraint generation (regtest for a crash).
|
|
for _ = range chA {
|
|
}
|
|
}
|
|
|
|
// Multi-word channel value in select with multiple receive cases.
|
|
// (Regtest for a crash.)
|
|
func chan5() {
|
|
type T struct {
|
|
x *int
|
|
y interface{}
|
|
}
|
|
ch := make(chan T)
|
|
ch <- T{new(int), incr} // @line ch5new
|
|
select {
|
|
case a := <-ch:
|
|
print(a.x) // @pointsto new@ch5new:13
|
|
print(a.y) // @types func(x int) int
|
|
case b := <-ch:
|
|
print(b.x) // @pointsto new@ch5new:13
|
|
print(b.y) // @types func(x int) int
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
chan1()
|
|
chan2()
|
|
chan3()
|
|
chan4()
|
|
chan5()
|
|
}
|