1// +build ignore 2 3package main 4 5func incr(x int) int { return x + 1 } 6 7func decr(x int) int { return x - 1 } 8 9var unknown bool // defeat dead-code elimination 10 11func chan1() { 12 chA := make(chan func(int) int, 0) // @line c1makeA 13 chB := make(chan func(int) int, 0) // @line c1makeB 14 chA <- incr 15 chB <- decr 16 chB <- func(int) int { return 1 } 17 18 print(chA) // @pointsto makechan@c1makeA:13 19 print(<-chA) // @pointsto main.incr 20 21 print(chB) // @pointsto makechan@c1makeB:13 22 print(<-chB) // @pointsto main.decr | main.chan1$1 23} 24 25func chan2() { 26 chA := make(chan func(int) int, 0) // @line c2makeA 27 chB := make(chan func(int) int, 0) // @line c2makeB 28 chA <- incr 29 chB <- decr 30 chB <- func(int) int { return 1 } 31 32 // Channels flow together. 33 // Labelsets remain distinct but elements are merged. 34 chAB := chA 35 if unknown { 36 chAB = chB 37 } 38 39 print(chA) // @pointsto makechan@c2makeA:13 40 print(<-chA) // @pointsto main.incr 41 42 print(chB) // @pointsto makechan@c2makeB:13 43 print(<-chB) // @pointsto main.decr | main.chan2$1 44 45 print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13 46 print(<-chAB) // @pointsto main.incr | main.decr | main.chan2$1 47 48 (<-chA)(3) 49} 50 51// @calls main.chan2 -> main.incr 52 53func chan3() { 54 chA := make(chan func(int) int, 0) // @line c3makeA 55 chB := make(chan func(int) int, 0) // @line c3makeB 56 chA <- incr 57 chB <- decr 58 chB <- func(int) int { return 1 } 59 print(chA) // @pointsto makechan@c3makeA:13 60 print(<-chA) // @pointsto main.incr 61 print(chB) // @pointsto makechan@c3makeB:13 62 print(<-chB) // @pointsto main.decr | main.chan3$1 63 64 (<-chA)(3) 65} 66 67// @calls main.chan3 -> main.incr 68 69func chan4() { 70 chA := make(chan func(int) int, 0) // @line c4makeA 71 chB := make(chan func(int) int, 0) // @line c4makeB 72 73 select { 74 case chA <- incr: 75 case chB <- decr: 76 case a := <-chA: 77 print(a) // @pointsto main.incr 78 case b := <-chB: 79 print(b) // @pointsto main.decr 80 default: 81 print(chA) // @pointsto makechan@c4makeA:13 82 print(chB) // @pointsto makechan@c4makeB:13 83 } 84 85 for k := range chA { 86 print(k) // @pointsto main.incr 87 } 88 // Exercise constraint generation (regtest for a crash). 89 for range chA { 90 } 91} 92 93// Multi-word channel value in select with multiple receive cases. 94// (Regtest for a crash.) 95func chan5() { 96 type T struct { 97 x *int 98 y interface{} 99 } 100 ch := make(chan T) 101 ch <- T{new(int), incr} // @line ch5new 102 select { 103 case a := <-ch: 104 print(a.x) // @pointsto new@ch5new:13 105 print(a.y) // @types func(x int) int 106 case b := <-ch: 107 print(b.x) // @pointsto new@ch5new:13 108 print(b.y) // @types func(x int) int 109 } 110} 111 112func main() { 113 chan1() 114 chan2() 115 chan3() 116 chan4() 117 chan5() 118} 119