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