mirror of
https://github.com/golang/go
synced 2024-11-19 00:54:42 -07:00
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()) // @concrete []*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()) // @concrete []*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()) // @concrete string
|
||
|
|
||
|
type S string
|
||
|
srv2 := reflect.ValueOf(S("hi")).Slice(0, 0)
|
||
|
print(srv2.Interface()) // @concrete 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()) // @concrete string | int
|
||
|
print(rv2.Interface()) // @concrete string | int
|
||
|
}
|
||
|
|
||
|
func arrayreflect5() {
|
||
|
sl1 := make([]byte, 0)
|
||
|
sl2 := make([]byte, 0)
|
||
|
|
||
|
srv := reflect.ValueOf(sl1)
|
||
|
|
||
|
print(srv.Interface()) // @concrete []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()) // @concrete []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()) // @concrete *bool
|
||
|
print(srv1.Index(42).Interface().(*bool)) // @pointsto alloc@testdata/arrayreflect.go:79:20
|
||
|
|
||
|
srv2 := reflect.ValueOf(sl2)
|
||
|
print(srv2.Index(42).Interface()) // @concrete *int
|
||
|
print(srv2.Index(42).Interface().(*int)) // @pointsto main.a
|
||
|
|
||
|
p1 := &sl1[0]
|
||
|
p2 := &sl2[0]
|
||
|
|
||
|
prv1 := reflect.ValueOf(p1)
|
||
|
print(prv1.Elem().Interface()) // @concrete *bool
|
||
|
print(prv1.Elem().Interface().(*bool)) // @pointsto alloc@testdata/arrayreflect.go:79:20
|
||
|
|
||
|
prv2 := reflect.ValueOf(p2)
|
||
|
print(prv2.Elem().Interface()) // @concrete *int
|
||
|
print(prv2.Elem().Interface().(*int)) // @pointsto main.a
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
arrayreflect1()
|
||
|
arrayreflect2()
|
||
|
arrayreflect3()
|
||
|
arrayreflect4()
|
||
|
arrayreflect5()
|
||
|
arrayreflect6()
|
||
|
}
|
||
|
|
||
|
var unknown bool
|