github.com/v2fly/tools@v0.100.0/go/pointer/testdata/reflect.go (about)

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