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