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