blob: 06849d9245bacee80c89a2d778850d4d87079a12 [file] [log] [blame]
// +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