1// +build ignore 2 3package main 4 5// Test of arrays & slices with reflection. 6 7import "reflect" 8 9var a, b int 10 11type S string 12 13func reflectValueSlice() { 14 // reflect.Value contains a slice. 15 slice := make([]*int, 10) // @line slice 16 slice[0] = &a 17 rvsl := reflect.ValueOf(slice).Slice(0, 0) 18 print(rvsl.Interface()) // @types []*int 19 print(rvsl.Interface().([]*int)) // @pointsto makeslice@slice:15 20 print(rvsl.Interface().([]*int)[42]) // @pointsto main.a 21 22 // reflect.Value contains an array (non-addressable). 23 array := [10]*int{&a} // @line array 24 rvarray := reflect.ValueOf(array).Slice(0, 0) 25 print(rvarray.Interface()) // @types 26 print(rvarray.Interface().([]*int)) // @pointsto 27 print(rvarray.Interface().([]*int)[42]) // @pointsto 28 29 // reflect.Value contains a pointer-to-array 30 rvparray := reflect.ValueOf(&array).Slice(0, 0) 31 print(rvparray.Interface()) // @types []*int 32 print(rvparray.Interface().([]*int)) // @pointsto array@array:2 33 print(rvparray.Interface().([]*int)[42]) // @pointsto main.a 34 35 // reflect.Value contains a string. 36 rvstring := reflect.ValueOf("hi").Slice(0, 0) 37 print(rvstring.Interface()) // @types string 38 39 // reflect.Value contains a (named) string type. 40 rvS := reflect.ValueOf(S("hi")).Slice(0, 0) 41 print(rvS.Interface()) // @types S 42 43 // reflect.Value contains a non-array pointer. 44 rvptr := reflect.ValueOf(new(int)).Slice(0, 0) 45 print(rvptr.Interface()) // @types 46 47 // reflect.Value contains a non-string basic type. 48 rvint := reflect.ValueOf(3).Slice(0, 0) 49 print(rvint.Interface()) // @types 50} 51 52func reflectValueBytes() { 53 sl1 := make([]byte, 0) // @line ar5sl1 54 sl2 := make([]byte, 0) // @line ar5sl2 55 56 rvsl1 := reflect.ValueOf(sl1) 57 print(rvsl1.Interface()) // @types []byte 58 print(rvsl1.Interface().([]byte)) // @pointsto makeslice@ar5sl1:13 59 print(rvsl1.Bytes()) // @pointsto makeslice@ar5sl1:13 60 61 rvsl2 := reflect.ValueOf(123) 62 rvsl2.SetBytes(sl2) 63 print(rvsl2.Interface()) // @types int 64 print(rvsl2.Interface().([]byte)) // @pointsto 65 print(rvsl2.Bytes()) // @pointsto 66 67 rvsl3 := reflect.ValueOf([]byte(nil)) 68 rvsl3.SetBytes(sl2) 69 print(rvsl3.Interface()) // @types []byte 70 print(rvsl3.Interface().([]byte)) // @pointsto makeslice@ar5sl2:13 71 print(rvsl3.Bytes()) // @pointsto makeslice@ar5sl2:13 72} 73 74func reflectValueIndex() { 75 slice := []*int{&a} // @line ar6slice 76 rv1 := reflect.ValueOf(slice) 77 print(rv1.Index(42).Interface()) // @types *int 78 print(rv1.Index(42).Interface().(*int)) // @pointsto main.a 79 80 array := [10]*int{&a} 81 rv2 := reflect.ValueOf(array) 82 print(rv2.Index(42).Interface()) // @types *int 83 print(rv2.Index(42).Interface().(*int)) // @pointsto main.a 84 85 rv3 := reflect.ValueOf("string") 86 print(rv3.Index(42).Interface()) // @types rune 87 88 rv4 := reflect.ValueOf(&array) 89 print(rv4.Index(42).Interface()) // @types 90 91 rv5 := reflect.ValueOf(3) 92 print(rv5.Index(42).Interface()) // @types 93} 94 95func reflectValueElem() { 96 // Interface. 97 var iface interface{} = &a 98 rv1 := reflect.ValueOf(&iface).Elem() 99 print(rv1.Interface()) // @types *int 100 print(rv1.Interface().(*int)) // @pointsto main.a 101 print(rv1.Elem().Interface()) // @types *int 102 print(rv1.Elem().Interface().(*int)) // @pointsto main.a 103 104 print(reflect.ValueOf(new(interface{})).Elem().Elem()) // @types 105 106 // Pointer. 107 ptr := &a 108 rv2 := reflect.ValueOf(&ptr) 109 print(rv2.Elem().Interface()) // @types *int 110 print(rv2.Elem().Interface().(*int)) // @pointsto main.a 111 112 // No other type works with (rV).Elem, not even those that 113 // work with (rT).Elem: slice, array, map, chan. 114 115 rv3 := reflect.ValueOf([]*int{&a}) 116 print(rv3.Elem().Interface()) // @types 117 118 rv4 := reflect.ValueOf([10]*int{&a}) 119 print(rv4.Elem().Interface()) // @types 120 121 rv5 := reflect.ValueOf(map[*int]*int{&a: &b}) 122 print(rv5.Elem().Interface()) // @types 123 124 ch := make(chan *int) 125 ch <- &a 126 rv6 := reflect.ValueOf(ch) 127 print(rv6.Elem().Interface()) // @types 128 129 rv7 := reflect.ValueOf(3) 130 print(rv7.Elem().Interface()) // @types 131} 132 133func reflectTypeElem() { 134 rt1 := reflect.TypeOf(make([]*int, 0)) 135 print(reflect.Zero(rt1.Elem())) // @types *int 136 137 rt2 := reflect.TypeOf([10]*int{}) 138 print(reflect.Zero(rt2.Elem())) // @types *int 139 140 rt3 := reflect.TypeOf(map[*int]*int{}) 141 print(reflect.Zero(rt3.Elem())) // @types *int 142 143 rt4 := reflect.TypeOf(make(chan *int)) 144 print(reflect.Zero(rt4.Elem())) // @types *int 145 146 ptr := &a 147 rt5 := reflect.TypeOf(&ptr) 148 print(reflect.Zero(rt5.Elem())) // @types *int 149 150 rt6 := reflect.TypeOf(3) 151 print(reflect.Zero(rt6.Elem())) // @types 152} 153 154func reflectPtrTo() { 155 tInt := reflect.TypeOf(3) 156 tPtrInt := reflect.PtrTo(tInt) 157 print(reflect.Zero(tPtrInt)) // @types *int 158 tPtrPtrInt := reflect.PtrTo(tPtrInt) 159 print(reflect.Zero(tPtrPtrInt)) // @types **int 160} 161 162func reflectSliceOf() { 163 tInt := reflect.TypeOf(3) 164 tSliceInt := reflect.SliceOf(tInt) 165 print(reflect.Zero(tSliceInt)) // @types []int 166} 167 168type T struct{ x int } 169 170func reflectMakeSlice() { 171 rt := []reflect.Type{ 172 reflect.TypeOf(3), 173 reflect.TypeOf([]int{}), 174 reflect.TypeOf([]T{}), 175 }[0] 176 sl := reflect.MakeSlice(rt, 0, 0) 177 print(sl) // @types []int | []T 178 print(sl) // @pointsto <alloc in reflect.MakeSlice> | <alloc in reflect.MakeSlice> 179 print(&sl.Interface().([]T)[0].x) // @pointsto <alloc in reflect.MakeSlice>[*].x 180} 181 182func main() { 183 reflectValueSlice() 184 reflectValueBytes() 185 reflectValueIndex() 186 reflectValueElem() 187 reflectTypeElem() 188 reflectPtrTo() 189 reflectSliceOf() 190 reflectMakeSlice() 191} 192