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