1 | //go:build ignore |
---|---|
2 | // +build ignore |
3 | |
4 | package main |
5 | |
6 | // Test of maps with reflection. |
7 | |
8 | import "reflect" |
9 | |
10 | var a int |
11 | var b bool |
12 | |
13 | func reflectMapKeysIndex() { |
14 | m := make(map[*int]*bool) // @line mr1make |
15 | m[&a] = &b |
16 | |
17 | mrv := reflect.ValueOf(m) |
18 | print(mrv.Interface()) // @types map[*int]*bool |
19 | print(mrv.Interface().(map[*int]*bool)) // @pointsto makemap@mr1make:11 |
20 | print(mrv) // @pointsto makeinterface:map[*int]*bool |
21 | print(mrv) // @types map[*int]*bool |
22 | |
23 | keys := mrv.MapKeys() |
24 | print(keys) // @pointsto <alloc in (reflect.Value).MapKeys> |
25 | for _, k := range keys { |
26 | print(k) // @pointsto <alloc in (reflect.Value).MapKeys> |
27 | print(k) // @types *int |
28 | print(k.Interface()) // @types *int |
29 | print(k.Interface().(*int)) // @pointsto command-line-arguments.a |
30 | |
31 | v := mrv.MapIndex(k) |
32 | print(v.Interface()) // @types *bool |
33 | print(v.Interface().(*bool)) // @pointsto command-line-arguments.b |
34 | } |
35 | } |
36 | |
37 | func reflectSetMapIndex() { |
38 | m := make(map[*int]*bool) |
39 | mrv := reflect.ValueOf(m) |
40 | mrv.SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b)) |
41 | |
42 | print(m[nil]) // @pointsto command-line-arguments.b |
43 | |
44 | for _, k := range mrv.MapKeys() { |
45 | print(k.Interface()) // @types *int |
46 | print(k.Interface().(*int)) // @pointsto command-line-arguments.a |
47 | } |
48 | |
49 | tmap := reflect.TypeOf(m) |
50 | // types.EvalNode won't let us refer to non-exported types: |
51 | // print(tmap) // #@types *reflect.rtype |
52 | print(tmap) // @pointsto map[*int]*bool |
53 | |
54 | zmap := reflect.Zero(tmap) |
55 | print(zmap) // @pointsto <alloc in reflect.Zero> |
56 | print(zmap.Interface()) // @pointsto <alloc in reflect.Zero> |
57 | |
58 | print(tmap.Key()) // @pointsto *int |
59 | print(tmap.Elem()) // @pointsto *bool |
60 | print(reflect.Zero(tmap.Key())) // @pointsto <alloc in reflect.Zero> |
61 | print(reflect.Zero(tmap.Key()).Interface()) // @pointsto <alloc in reflect.Zero> |
62 | print(reflect.Zero(tmap.Key()).Interface()) // @types *int |
63 | print(reflect.Zero(tmap.Elem())) // @pointsto <alloc in reflect.Zero> |
64 | print(reflect.Zero(tmap.Elem()).Interface()) // @pointsto <alloc in reflect.Zero> |
65 | print(reflect.Zero(tmap.Elem()).Interface()) // @types *bool |
66 | } |
67 | |
68 | func reflectSetMapIndexInterface() { |
69 | // Exercises reflect.Value conversions to/from interfaces: |
70 | // a different code path than for concrete types. |
71 | m := make(map[interface{}]interface{}) |
72 | reflect.ValueOf(m).SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b)) |
73 | for k, v := range m { |
74 | print(k) // @types *int |
75 | print(k.(*int)) // @pointsto command-line-arguments.a |
76 | print(v) // @types *bool |
77 | print(v.(*bool)) // @pointsto command-line-arguments.b |
78 | } |
79 | } |
80 | |
81 | func reflectSetMapIndexAssignable() { |
82 | // SetMapIndex performs implicit assignability conversions. |
83 | type I *int |
84 | type J *int |
85 | |
86 | str := reflect.ValueOf("") |
87 | |
88 | // *int is assignable to I. |
89 | m1 := make(map[string]I) |
90 | reflect.ValueOf(m1).SetMapIndex(str, reflect.ValueOf(new(int))) // @line int |
91 | print(m1[""]) // @pointsto new@int:58 |
92 | |
93 | // I is assignable to I. |
94 | m2 := make(map[string]I) |
95 | reflect.ValueOf(m2).SetMapIndex(str, reflect.ValueOf(I(new(int)))) // @line I |
96 | print(m2[""]) // @pointsto new@I:60 |
97 | |
98 | // J is not assignable to I. |
99 | m3 := make(map[string]I) |
100 | reflect.ValueOf(m3).SetMapIndex(str, reflect.ValueOf(J(new(int)))) |
101 | print(m3[""]) // @pointsto |
102 | } |
103 | |
104 | func reflectMakeMap() { |
105 | t := reflect.TypeOf(map[*int]*bool(nil)) |
106 | v := reflect.MakeMap(t) |
107 | print(v) // @types map[*int]*bool |
108 | print(v) // @pointsto <alloc in reflect.MakeMap> |
109 | } |
110 | |
111 | func main() { |
112 | reflectMapKeysIndex() |
113 | reflectSetMapIndex() |
114 | reflectSetMapIndexInterface() |
115 | reflectSetMapIndexAssignable() |
116 | reflectMakeMap() |
117 | // TODO(adonovan): reflect.MapOf(Type) |
118 | } |
119 |
Members