| 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 | } |
| 193 |
Members