github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/chanreflect.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 import "reflect" 7 8 // Test of channels with reflection. 9 10 var a, b int 11 12 func chanreflect1() { 13 ch := make(chan *int, 0) // @line cr1make 14 crv := reflect.ValueOf(ch) 15 crv.Send(reflect.ValueOf(&a)) 16 print(crv.Interface()) // @types chan *int 17 print(crv.Interface().(chan *int)) // @pointsto makechan@cr1make:12 18 print(<-ch) // @pointsto command-line-arguments.a 19 } 20 21 func chanreflect1i() { 22 // Exercises reflect.Value conversions to/from interfaces: 23 // a different code path than for concrete types. 24 ch := make(chan interface{}, 0) 25 reflect.ValueOf(ch).Send(reflect.ValueOf(&a)) 26 v := <-ch 27 print(v) // @types *int 28 print(v.(*int)) // @pointsto command-line-arguments.a 29 } 30 31 func chanreflect2() { 32 ch := make(chan *int, 0) 33 ch <- &b 34 crv := reflect.ValueOf(ch) 35 r, _ := crv.Recv() 36 print(r.Interface()) // @types *int 37 print(r.Interface().(*int)) // @pointsto command-line-arguments.b 38 } 39 40 func chanOfRecv() { 41 // MakeChan(<-chan) is a no-op. 42 t := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(&a)) 43 print(reflect.Zero(t).Interface()) // @types <-chan *int 44 print(reflect.MakeChan(t, 0).Interface().(<-chan *int)) // @pointsto 45 print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto 46 } 47 48 func chanOfSend() { 49 // MakeChan(chan<-) is a no-op. 50 t := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(&a)) 51 print(reflect.Zero(t).Interface()) // @types chan<- *int 52 print(reflect.MakeChan(t, 0).Interface().(chan<- *int)) // @pointsto 53 print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto 54 } 55 56 func chanOfBoth() { 57 t := reflect.ChanOf(reflect.BothDir, reflect.TypeOf(&a)) 58 print(reflect.Zero(t).Interface()) // @types chan *int 59 ch := reflect.MakeChan(t, 0) 60 print(ch.Interface().(chan *int)) // @pointsto <alloc in reflect.MakeChan> 61 ch.Send(reflect.ValueOf(&b)) 62 ch.Interface().(chan *int) <- &a 63 r, _ := ch.Recv() 64 print(r.Interface().(*int)) // @pointsto command-line-arguments.a | command-line-arguments.b 65 print(<-ch.Interface().(chan *int)) // @pointsto command-line-arguments.a | command-line-arguments.b 66 } 67 68 var unknownDir reflect.ChanDir // not a constant 69 70 func chanOfUnknown() { 71 // Unknown channel direction: assume all three. 72 // MakeChan only works on the bi-di channel type. 73 t := reflect.ChanOf(unknownDir, reflect.TypeOf(&a)) 74 print(reflect.Zero(t).Interface()) // @types <-chan *int | chan<- *int | chan *int 75 print(reflect.MakeChan(t, 0).Interface()) // @types chan *int 76 } 77 78 func main() { 79 chanreflect1() 80 chanreflect1i() 81 chanreflect2() 82 chanOfRecv() 83 chanOfSend() 84 chanOfBoth() 85 chanOfUnknown() 86 }