109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
| // +build ignore
 | |
| 
 | |
| package main
 | |
| 
 | |
| import "reflect"
 | |
| 
 | |
| // Test of arrays & slices with reflection.
 | |
| 
 | |
| var a int
 | |
| 
 | |
| func arrayreflect1() {
 | |
| 	sl := make([]*int, 10) // @line ar1make
 | |
| 	sl[0] = &a
 | |
| 
 | |
| 	srv := reflect.ValueOf(sl).Slice(0, 0)
 | |
| 	print(srv.Interface())              // @types []*int
 | |
| 	print(srv.Interface().([]*int))     // @pointsto makeslice@ar1make:12
 | |
| 	print(srv.Interface().([]*int)[42]) // @pointsto main.a
 | |
| }
 | |
| 
 | |
| func arrayreflect2() {
 | |
| 	var arr [10]*int
 | |
| 	sl := arr[:]
 | |
| 	sl[0] = &a
 | |
| 
 | |
| 	srv := reflect.ValueOf(sl).Slice(0, 0)
 | |
| 	print(srv.Interface())              // @types []*int
 | |
| 	print(srv.Interface().([]*int))     // pointsto TODO
 | |
| 	print(srv.Interface().([]*int)[42]) // @pointsto main.a
 | |
| }
 | |
| 
 | |
| func arrayreflect3() {
 | |
| 	srv := reflect.ValueOf("hi").Slice(0, 0)
 | |
| 	print(srv.Interface()) // @types string
 | |
| 
 | |
| 	type S string
 | |
| 	srv2 := reflect.ValueOf(S("hi")).Slice(0, 0)
 | |
| 	print(srv2.Interface()) // @types main.S
 | |
| }
 | |
| 
 | |
| func arrayreflect4() {
 | |
| 	rv1 := reflect.ValueOf("hi")
 | |
| 	rv2 := rv1 // backflow!
 | |
| 	if unknown {
 | |
| 		rv2 = reflect.ValueOf(123)
 | |
| 	}
 | |
| 	// We see backflow through the assignment above causing an
 | |
| 	// imprecise result for rv1.  This is because the SSA builder
 | |
| 	// doesn't yet lift structs (like reflect.Value) into
 | |
| 	// registers so these are all loads/stores to the stack.
 | |
| 	// Under Das's algorithm, the extra indirection results in
 | |
| 	// (undirected) unification not (directed) flow edges.
 | |
| 	// TODO(adonovan): precision: lift aggregates.
 | |
| 	print(rv1.Interface()) // @types string | int
 | |
| 	print(rv2.Interface()) // @types string | int
 | |
| }
 | |
| 
 | |
| func arrayreflect5() {
 | |
| 	sl1 := make([]byte, 0)
 | |
| 	sl2 := make([]byte, 0)
 | |
| 
 | |
| 	srv := reflect.ValueOf(sl1)
 | |
| 
 | |
| 	print(srv.Interface())          // @types []byte
 | |
| 	print(srv.Interface().([]byte)) // @pointsto makeslice@testdata/arrayreflect.go:62:13
 | |
| 	print(srv.Bytes())              // @pointsto makeslice@testdata/arrayreflect.go:62:13
 | |
| 
 | |
| 	srv2 := reflect.ValueOf(123)
 | |
| 	srv2.SetBytes(sl2)
 | |
| 	print(srv2.Interface())          // @types []byte | int
 | |
| 	print(srv2.Interface().([]byte)) // @pointsto makeslice@testdata/arrayreflect.go:63:13
 | |
| 	print(srv2.Bytes())              // @pointsto makeslice@testdata/arrayreflect.go:63:13
 | |
| }
 | |
| 
 | |
| func arrayreflect6() {
 | |
| 	sl1 := []*bool{new(bool)}
 | |
| 	sl2 := []*int{&a}
 | |
| 
 | |
| 	srv1 := reflect.ValueOf(sl1)
 | |
| 	print(srv1.Index(42).Interface())         // @types *bool
 | |
| 	print(srv1.Index(42).Interface().(*bool)) // @pointsto alloc@testdata/arrayreflect.go:79:20
 | |
| 
 | |
| 	srv2 := reflect.ValueOf(sl2)
 | |
| 	print(srv2.Index(42).Interface())        // @types *int
 | |
| 	print(srv2.Index(42).Interface().(*int)) // @pointsto main.a
 | |
| 
 | |
| 	p1 := &sl1[0]
 | |
| 	p2 := &sl2[0]
 | |
| 
 | |
| 	prv1 := reflect.ValueOf(p1)
 | |
| 	print(prv1.Elem().Interface())         // @types *bool
 | |
| 	print(prv1.Elem().Interface().(*bool)) // @pointsto alloc@testdata/arrayreflect.go:79:20
 | |
| 
 | |
| 	prv2 := reflect.ValueOf(p2)
 | |
| 	print(prv2.Elem().Interface())        // @types *int
 | |
| 	print(prv2.Elem().Interface().(*int)) // @pointsto main.a
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	arrayreflect1()
 | |
| 	arrayreflect2()
 | |
| 	arrayreflect3()
 | |
| 	arrayreflect4()
 | |
| 	arrayreflect5()
 | |
| 	arrayreflect6()
 | |
| }
 | |
| 
 | |
| var unknown bool
 |