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
 |