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  }