| 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 | } |
| 87 |
Members