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