blob: 377b68a56b6060b7b81fd5b82d3f74819155b792 [file] [log] [blame]
// +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 | main.chan1$1
}
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 | main.chan2$1
print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13
print(<-chAB) // @pointsto main.incr | main.decr | main.chan2$1
(<-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 | main.chan3$1
(<-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()
}