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