github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/reflect.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  package main
     5  
     6  import (
     7  	"reflect"
     8  	"unsafe"
     9  )
    10  
    11  var a, b int
    12  var unknown bool
    13  
    14  func reflectIndirect() {
    15  	ptr := &a
    16  	// Pointer:
    17  	print(reflect.Indirect(reflect.ValueOf(&ptr)).Interface().(*int)) // @pointsto command-line-arguments.a
    18  	// Non-pointer:
    19  	print(reflect.Indirect(reflect.ValueOf([]*int{ptr})).Interface().([]*int)[0]) // @pointsto command-line-arguments.a
    20  }
    21  
    22  func reflectNewAt() {
    23  	var x [8]byte
    24  	print(reflect.NewAt(reflect.TypeOf(3), unsafe.Pointer(&x)).Interface()) // @types *int
    25  }
    26  
    27  // @warning "unsound: command-line-arguments.reflectNewAt contains a reflect.NewAt.. call"
    28  
    29  func reflectTypeOf() {
    30  	t := reflect.TypeOf(3)
    31  	if unknown {
    32  		t = reflect.TypeOf("foo")
    33  	}
    34  	// TODO(adonovan): make types.Eval let us refer to unexported types.
    35  	print(t)                             // #@types *reflect.rtype
    36  	print(reflect.Zero(t).Interface())   // @types int | string
    37  	newint := reflect.New(t).Interface() // @line rtonew
    38  	print(newint)                        // @types *int | *string
    39  	print(newint.(*int))                 // @pointsto <alloc in reflect.New>
    40  	print(newint.(*string))              // @pointsto <alloc in reflect.New>
    41  }
    42  
    43  func reflectTypeElem() {
    44  	print(reflect.Zero(reflect.TypeOf(&a).Elem()).Interface())                       // @types int
    45  	print(reflect.Zero(reflect.TypeOf([]string{}).Elem()).Interface())               // @types string
    46  	print(reflect.Zero(reflect.TypeOf(make(chan bool)).Elem()).Interface())          // @types bool
    47  	print(reflect.Zero(reflect.TypeOf(make(map[string]float64)).Elem()).Interface()) // @types float64
    48  	print(reflect.Zero(reflect.TypeOf([3]complex64{}).Elem()).Interface())           // @types complex64
    49  	print(reflect.Zero(reflect.TypeOf(3).Elem()).Interface())                        // @types
    50  	print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()))                     // @types interface{}
    51  	print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()).Interface())         // @types
    52  }
    53  
    54  // reflect.Values within reflect.Values.
    55  func metareflection() {
    56  	// "box" a *int twice, unbox it twice.
    57  	v0 := reflect.ValueOf(&a)
    58  	print(v0)                              // @types *int
    59  	v1 := reflect.ValueOf(v0)              // box
    60  	print(v1)                              // @types reflect.Value
    61  	v2 := reflect.ValueOf(v1)              // box
    62  	print(v2)                              // @types reflect.Value
    63  	v1a := v2.Interface().(reflect.Value)  // unbox
    64  	print(v1a)                             // @types reflect.Value
    65  	v0a := v1a.Interface().(reflect.Value) // unbox
    66  	print(v0a)                             // @types *int
    67  	print(v0a.Interface().(*int))          // @pointsto command-line-arguments.a
    68  
    69  	// "box" an interface{} lvalue twice, unbox it twice.
    70  	var iface interface{} = 3
    71  	x0 := reflect.ValueOf(&iface).Elem()
    72  	print(x0)                              // @types interface{}
    73  	x1 := reflect.ValueOf(x0)              // box
    74  	print(x1)                              // @types reflect.Value
    75  	x2 := reflect.ValueOf(x1)              // box
    76  	print(x2)                              // @types reflect.Value
    77  	x1a := x2.Interface().(reflect.Value)  // unbox
    78  	print(x1a)                             // @types reflect.Value
    79  	x0a := x1a.Interface().(reflect.Value) // unbox
    80  	print(x0a)                             // @types interface{}
    81  	print(x0a.Interface())                 // @types int
    82  }
    83  
    84  type T struct{}
    85  
    86  // When the output of a type constructor flows to its input, we must
    87  // bound the set of types created to ensure termination of the algorithm.
    88  func typeCycle() {
    89  	t := reflect.TypeOf(0)
    90  	u := reflect.TypeOf("")
    91  	v := reflect.TypeOf(T{})
    92  	for unknown {
    93  		t = reflect.PtrTo(t)
    94  		t = reflect.SliceOf(t)
    95  
    96  		u = reflect.SliceOf(u)
    97  
    98  		if unknown {
    99  			v = reflect.ChanOf(reflect.BothDir, v)
   100  		} else {
   101  			v = reflect.PtrTo(v)
   102  		}
   103  	}
   104  
   105  	// Type height is bounded to about 4 map/slice/chan/pointer constructors.
   106  	print(reflect.Zero(t).Interface()) // @types int | []*int | []*[]*int
   107  	print(reflect.Zero(u).Interface()) // @types string | []string | [][]string | [][][]string | [][][][]string
   108  	print(reflect.Zero(v).Interface()) // @types T | *T | **T | ***T | ****T | chan T | *chan T | **chan T | chan *T | *chan *T | chan **T | chan ***T | chan chan T | chan *chan T | chan chan *T
   109  }
   110  
   111  func main() {
   112  	reflectIndirect()
   113  	reflectNewAt()
   114  	reflectTypeOf()
   115  	reflectTypeElem()
   116  	metareflection()
   117  	typeCycle()
   118  }