Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
42
vendor/golang.org/x/tools/go/pointer/testdata/a_test.go
generated
vendored
Normal file
42
vendor/golang.org/x/tools/go/pointer/testdata/a_test.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// +build ignore
|
||||
|
||||
package a
|
||||
|
||||
// This test exercises the synthesis of testmain packages for tests.
|
||||
// The test framework doesn't directly let us perform negative
|
||||
// assertions (i.e. that TestingQuux isn't called, or that its
|
||||
// parameter's PTS is empty) so this test is rather roundabout.
|
||||
|
||||
import "testing"
|
||||
|
||||
func log(f func(*testing.T)) {
|
||||
// The PTS of f is the set of called tests. TestingQuux is not present.
|
||||
print(f) // @pointsto main.Test | main.TestFoo
|
||||
}
|
||||
|
||||
func Test(t *testing.T) {
|
||||
// Don't assert @pointsto(t) since its label contains a fragile line number.
|
||||
log(Test)
|
||||
}
|
||||
|
||||
func TestFoo(t *testing.T) {
|
||||
// Don't assert @pointsto(t) since its label contains a fragile line number.
|
||||
log(TestFoo)
|
||||
}
|
||||
|
||||
func TestingQuux(t *testing.T) {
|
||||
// We can't assert @pointsto(t) since this is dead code.
|
||||
log(TestingQuux)
|
||||
}
|
||||
|
||||
func BenchmarkFoo(b *testing.B) {
|
||||
}
|
||||
|
||||
func ExampleBar() {
|
||||
}
|
||||
|
||||
// Excludes TestingQuux.
|
||||
// @calls testing.tRunner -> main.Test
|
||||
// @calls testing.tRunner -> main.TestFoo
|
||||
// @calls testing.runExample -> main.ExampleBar
|
||||
// @calls (*testing.B).runN -> main.BenchmarkFoo
|
36
vendor/golang.org/x/tools/go/pointer/testdata/another.go
generated
vendored
Normal file
36
vendor/golang.org/x/tools/go/pointer/testdata/another.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var unknown bool
|
||||
|
||||
type S string
|
||||
|
||||
func incr(x int) int { return x + 1 }
|
||||
|
||||
func main() {
|
||||
var i interface{}
|
||||
i = 1
|
||||
if unknown {
|
||||
i = S("foo")
|
||||
}
|
||||
if unknown {
|
||||
i = (func(int, int))(nil) // NB type compares equal to that below.
|
||||
}
|
||||
// Look, the test harness can handle equal-but-not-String-equal
|
||||
// types because we parse types and using a typemap.
|
||||
if unknown {
|
||||
i = (func(x int, y int))(nil)
|
||||
}
|
||||
if unknown {
|
||||
i = incr
|
||||
}
|
||||
print(i) // @types int | S | func(int, int) | func(int) int
|
||||
|
||||
// NB, an interface may never directly alias any global
|
||||
// labels, even though it may contain pointers that do.
|
||||
print(i) // @pointsto makeinterface:func(x int) int | makeinterface:func(x int, y int) | makeinterface:func(int, int) | makeinterface:int | makeinterface:main.S
|
||||
print(i.(func(int) int)) // @pointsto main.incr
|
||||
|
||||
print() // regression test for crash
|
||||
}
|
191
vendor/golang.org/x/tools/go/pointer/testdata/arrayreflect.go
generated
vendored
Normal file
191
vendor/golang.org/x/tools/go/pointer/testdata/arrayreflect.go
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Test of arrays & slices with reflection.
|
||||
|
||||
import "reflect"
|
||||
|
||||
var a, b int
|
||||
|
||||
type S string
|
||||
|
||||
func reflectValueSlice() {
|
||||
// reflect.Value contains a slice.
|
||||
slice := make([]*int, 10) // @line slice
|
||||
slice[0] = &a
|
||||
rvsl := reflect.ValueOf(slice).Slice(0, 0)
|
||||
print(rvsl.Interface()) // @types []*int
|
||||
print(rvsl.Interface().([]*int)) // @pointsto makeslice@slice:15
|
||||
print(rvsl.Interface().([]*int)[42]) // @pointsto main.a
|
||||
|
||||
// reflect.Value contains an array (non-addressable).
|
||||
array := [10]*int{&a} // @line array
|
||||
rvarray := reflect.ValueOf(array).Slice(0, 0)
|
||||
print(rvarray.Interface()) // @types
|
||||
print(rvarray.Interface().([]*int)) // @pointsto
|
||||
print(rvarray.Interface().([]*int)[42]) // @pointsto
|
||||
|
||||
// reflect.Value contains a pointer-to-array
|
||||
rvparray := reflect.ValueOf(&array).Slice(0, 0)
|
||||
print(rvparray.Interface()) // @types []*int
|
||||
print(rvparray.Interface().([]*int)) // @pointsto array@array:2
|
||||
print(rvparray.Interface().([]*int)[42]) // @pointsto main.a
|
||||
|
||||
// reflect.Value contains a string.
|
||||
rvstring := reflect.ValueOf("hi").Slice(0, 0)
|
||||
print(rvstring.Interface()) // @types string
|
||||
|
||||
// reflect.Value contains a (named) string type.
|
||||
rvS := reflect.ValueOf(S("hi")).Slice(0, 0)
|
||||
print(rvS.Interface()) // @types S
|
||||
|
||||
// reflect.Value contains a non-array pointer.
|
||||
rvptr := reflect.ValueOf(new(int)).Slice(0, 0)
|
||||
print(rvptr.Interface()) // @types
|
||||
|
||||
// reflect.Value contains a non-string basic type.
|
||||
rvint := reflect.ValueOf(3).Slice(0, 0)
|
||||
print(rvint.Interface()) // @types
|
||||
}
|
||||
|
||||
func reflectValueBytes() {
|
||||
sl1 := make([]byte, 0) // @line ar5sl1
|
||||
sl2 := make([]byte, 0) // @line ar5sl2
|
||||
|
||||
rvsl1 := reflect.ValueOf(sl1)
|
||||
print(rvsl1.Interface()) // @types []byte
|
||||
print(rvsl1.Interface().([]byte)) // @pointsto makeslice@ar5sl1:13
|
||||
print(rvsl1.Bytes()) // @pointsto makeslice@ar5sl1:13
|
||||
|
||||
rvsl2 := reflect.ValueOf(123)
|
||||
rvsl2.SetBytes(sl2)
|
||||
print(rvsl2.Interface()) // @types int
|
||||
print(rvsl2.Interface().([]byte)) // @pointsto
|
||||
print(rvsl2.Bytes()) // @pointsto
|
||||
|
||||
rvsl3 := reflect.ValueOf([]byte(nil))
|
||||
rvsl3.SetBytes(sl2)
|
||||
print(rvsl3.Interface()) // @types []byte
|
||||
print(rvsl3.Interface().([]byte)) // @pointsto makeslice@ar5sl2:13
|
||||
print(rvsl3.Bytes()) // @pointsto makeslice@ar5sl2:13
|
||||
}
|
||||
|
||||
func reflectValueIndex() {
|
||||
slice := []*int{&a} // @line ar6slice
|
||||
rv1 := reflect.ValueOf(slice)
|
||||
print(rv1.Index(42).Interface()) // @types *int
|
||||
print(rv1.Index(42).Interface().(*int)) // @pointsto main.a
|
||||
|
||||
array := [10]*int{&a}
|
||||
rv2 := reflect.ValueOf(array)
|
||||
print(rv2.Index(42).Interface()) // @types *int
|
||||
print(rv2.Index(42).Interface().(*int)) // @pointsto main.a
|
||||
|
||||
rv3 := reflect.ValueOf("string")
|
||||
print(rv3.Index(42).Interface()) // @types rune
|
||||
|
||||
rv4 := reflect.ValueOf(&array)
|
||||
print(rv4.Index(42).Interface()) // @types
|
||||
|
||||
rv5 := reflect.ValueOf(3)
|
||||
print(rv5.Index(42).Interface()) // @types
|
||||
}
|
||||
|
||||
func reflectValueElem() {
|
||||
// Interface.
|
||||
var iface interface{} = &a
|
||||
rv1 := reflect.ValueOf(&iface).Elem()
|
||||
print(rv1.Interface()) // @types *int
|
||||
print(rv1.Interface().(*int)) // @pointsto main.a
|
||||
print(rv1.Elem().Interface()) // @types *int
|
||||
print(rv1.Elem().Interface().(*int)) // @pointsto main.a
|
||||
|
||||
print(reflect.ValueOf(new(interface{})).Elem().Elem()) // @types
|
||||
|
||||
// Pointer.
|
||||
ptr := &a
|
||||
rv2 := reflect.ValueOf(&ptr)
|
||||
print(rv2.Elem().Interface()) // @types *int
|
||||
print(rv2.Elem().Interface().(*int)) // @pointsto main.a
|
||||
|
||||
// No other type works with (rV).Elem, not even those that
|
||||
// work with (rT).Elem: slice, array, map, chan.
|
||||
|
||||
rv3 := reflect.ValueOf([]*int{&a})
|
||||
print(rv3.Elem().Interface()) // @types
|
||||
|
||||
rv4 := reflect.ValueOf([10]*int{&a})
|
||||
print(rv4.Elem().Interface()) // @types
|
||||
|
||||
rv5 := reflect.ValueOf(map[*int]*int{&a: &b})
|
||||
print(rv5.Elem().Interface()) // @types
|
||||
|
||||
ch := make(chan *int)
|
||||
ch <- &a
|
||||
rv6 := reflect.ValueOf(ch)
|
||||
print(rv6.Elem().Interface()) // @types
|
||||
|
||||
rv7 := reflect.ValueOf(3)
|
||||
print(rv7.Elem().Interface()) // @types
|
||||
}
|
||||
|
||||
func reflectTypeElem() {
|
||||
rt1 := reflect.TypeOf(make([]*int, 0))
|
||||
print(reflect.Zero(rt1.Elem())) // @types *int
|
||||
|
||||
rt2 := reflect.TypeOf([10]*int{})
|
||||
print(reflect.Zero(rt2.Elem())) // @types *int
|
||||
|
||||
rt3 := reflect.TypeOf(map[*int]*int{})
|
||||
print(reflect.Zero(rt3.Elem())) // @types *int
|
||||
|
||||
rt4 := reflect.TypeOf(make(chan *int))
|
||||
print(reflect.Zero(rt4.Elem())) // @types *int
|
||||
|
||||
ptr := &a
|
||||
rt5 := reflect.TypeOf(&ptr)
|
||||
print(reflect.Zero(rt5.Elem())) // @types *int
|
||||
|
||||
rt6 := reflect.TypeOf(3)
|
||||
print(reflect.Zero(rt6.Elem())) // @types
|
||||
}
|
||||
|
||||
func reflectPtrTo() {
|
||||
tInt := reflect.TypeOf(3)
|
||||
tPtrInt := reflect.PtrTo(tInt)
|
||||
print(reflect.Zero(tPtrInt)) // @types *int
|
||||
tPtrPtrInt := reflect.PtrTo(tPtrInt)
|
||||
print(reflect.Zero(tPtrPtrInt)) // @types **int
|
||||
}
|
||||
|
||||
func reflectSliceOf() {
|
||||
tInt := reflect.TypeOf(3)
|
||||
tSliceInt := reflect.SliceOf(tInt)
|
||||
print(reflect.Zero(tSliceInt)) // @types []int
|
||||
}
|
||||
|
||||
type T struct{ x int }
|
||||
|
||||
func reflectMakeSlice() {
|
||||
rt := []reflect.Type{
|
||||
reflect.TypeOf(3),
|
||||
reflect.TypeOf([]int{}),
|
||||
reflect.TypeOf([]T{}),
|
||||
}[0]
|
||||
sl := reflect.MakeSlice(rt, 0, 0)
|
||||
print(sl) // @types []int | []T
|
||||
print(sl) // @pointsto <alloc in reflect.MakeSlice> | <alloc in reflect.MakeSlice>
|
||||
print(&sl.Interface().([]T)[0].x) // @pointsto <alloc in reflect.MakeSlice>[*].x
|
||||
}
|
||||
|
||||
func main() {
|
||||
reflectValueSlice()
|
||||
reflectValueBytes()
|
||||
reflectValueIndex()
|
||||
reflectValueElem()
|
||||
reflectTypeElem()
|
||||
reflectPtrTo()
|
||||
reflectSliceOf()
|
||||
reflectMakeSlice()
|
||||
}
|
97
vendor/golang.org/x/tools/go/pointer/testdata/arrays.go
generated
vendored
Normal file
97
vendor/golang.org/x/tools/go/pointer/testdata/arrays.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
||||
|
||||
var a, b int
|
||||
|
||||
func array1() {
|
||||
sliceA := make([]*int, 10) // @line a1make
|
||||
sliceA[0] = &a
|
||||
|
||||
var sliceB []*int
|
||||
sliceB = append(sliceB, &b) // @line a1append
|
||||
|
||||
print(sliceA) // @pointsto makeslice@a1make:16
|
||||
print(sliceA[0]) // @pointsto main.a
|
||||
|
||||
print(sliceB) // @pointsto append@a1append:17
|
||||
print(sliceB[100]) // @pointsto main.b
|
||||
}
|
||||
|
||||
func array2() {
|
||||
sliceA := make([]*int, 10) // @line a2make
|
||||
sliceA[0] = &a
|
||||
|
||||
sliceB := sliceA[:]
|
||||
|
||||
print(sliceA) // @pointsto makeslice@a2make:16
|
||||
print(sliceA[0]) // @pointsto main.a
|
||||
|
||||
print(sliceB) // @pointsto makeslice@a2make:16
|
||||
print(sliceB[0]) // @pointsto main.a
|
||||
}
|
||||
|
||||
func array3() {
|
||||
a := []interface{}{"", 1}
|
||||
b := []interface{}{true, func() {}}
|
||||
print(a[0]) // @types string | int
|
||||
print(b[0]) // @types bool | func()
|
||||
}
|
||||
|
||||
// Test of append, copy, slice.
|
||||
func array4() {
|
||||
var s2 struct { // @line a4L0
|
||||
a [3]int
|
||||
b struct{ c, d int }
|
||||
}
|
||||
var sl1 = make([]*int, 10) // @line a4make
|
||||
var someint int // @line a4L1
|
||||
sl1[1] = &someint
|
||||
sl2 := append(sl1, &s2.a[1]) // @line a4append1
|
||||
print(sl1) // @pointsto makeslice@a4make:16
|
||||
print(sl2) // @pointsto append@a4append1:15 | makeslice@a4make:16
|
||||
print(sl1[0]) // @pointsto someint@a4L1:6 | s2.a[*]@a4L0:6
|
||||
print(sl2[0]) // @pointsto someint@a4L1:6 | s2.a[*]@a4L0:6
|
||||
|
||||
// In z=append(x,y) we should observe flow from y[*] to x[*].
|
||||
var sl3 = make([]*int, 10) // @line a4L2
|
||||
_ = append(sl3, &s2.a[1])
|
||||
print(sl3) // @pointsto makeslice@a4L2:16
|
||||
print(sl3[0]) // @pointsto s2.a[*]@a4L0:6
|
||||
|
||||
var sl4 = []*int{&a} // @line a4L3
|
||||
sl4a := append(sl4) // @line a4L4
|
||||
print(sl4a) // @pointsto slicelit@a4L3:18 | append@a4L4:16
|
||||
print(&sl4a[0]) // @pointsto slicelit[*]@a4L3:18 | append[*]@a4L4:16
|
||||
print(sl4a[0]) // @pointsto main.a
|
||||
|
||||
var sl5 = []*int{&b} // @line a4L5
|
||||
copy(sl5, sl4)
|
||||
print(sl5) // @pointsto slicelit@a4L5:18
|
||||
print(&sl5[0]) // @pointsto slicelit[*]@a4L5:18
|
||||
print(sl5[0]) // @pointsto main.b | main.a
|
||||
|
||||
var sl6 = sl5[:0]
|
||||
print(sl6) // @pointsto slicelit@a4L5:18
|
||||
print(&sl6[0]) // @pointsto slicelit[*]@a4L5:18
|
||||
print(sl6[0]) // @pointsto main.b | main.a
|
||||
}
|
||||
|
||||
func array5() {
|
||||
var arr [2]*int
|
||||
arr[0] = &a
|
||||
arr[1] = &b
|
||||
|
||||
var n int
|
||||
print(arr[n]) // @pointsto main.a | main.b
|
||||
}
|
||||
|
||||
func main() {
|
||||
array1()
|
||||
array2()
|
||||
array3()
|
||||
array4()
|
||||
array5()
|
||||
}
|
118
vendor/golang.org/x/tools/go/pointer/testdata/channels.go
generated
vendored
Normal file
118
vendor/golang.org/x/tools/go/pointer/testdata/channels.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
func incr(x int) int { return x + 1 }
|
||||
|
||||
func decr(x int) int { return x - 1 }
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
||||
|
||||
func chan1() {
|
||||
chA := make(chan func(int) int, 0) // @line c1makeA
|
||||
chB := make(chan func(int) int, 0) // @line c1makeB
|
||||
chA <- incr
|
||||
chB <- decr
|
||||
chB <- func(int) int { return 1 }
|
||||
|
||||
print(chA) // @pointsto makechan@c1makeA:13
|
||||
print(<-chA) // @pointsto main.incr
|
||||
|
||||
print(chB) // @pointsto makechan@c1makeB:13
|
||||
print(<-chB) // @pointsto main.decr | main.chan1$1
|
||||
}
|
||||
|
||||
func chan2() {
|
||||
chA := make(chan func(int) int, 0) // @line c2makeA
|
||||
chB := make(chan func(int) int, 0) // @line c2makeB
|
||||
chA <- incr
|
||||
chB <- decr
|
||||
chB <- func(int) int { return 1 }
|
||||
|
||||
// Channels flow together.
|
||||
// Labelsets remain distinct but elements are merged.
|
||||
chAB := chA
|
||||
if unknown {
|
||||
chAB = chB
|
||||
}
|
||||
|
||||
print(chA) // @pointsto makechan@c2makeA:13
|
||||
print(<-chA) // @pointsto main.incr
|
||||
|
||||
print(chB) // @pointsto makechan@c2makeB:13
|
||||
print(<-chB) // @pointsto main.decr | main.chan2$1
|
||||
|
||||
print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13
|
||||
print(<-chAB) // @pointsto main.incr | main.decr | main.chan2$1
|
||||
|
||||
(<-chA)(3)
|
||||
}
|
||||
|
||||
// @calls main.chan2 -> main.incr
|
||||
|
||||
func chan3() {
|
||||
chA := make(chan func(int) int, 0) // @line c3makeA
|
||||
chB := make(chan func(int) int, 0) // @line c3makeB
|
||||
chA <- incr
|
||||
chB <- decr
|
||||
chB <- func(int) int { return 1 }
|
||||
print(chA) // @pointsto makechan@c3makeA:13
|
||||
print(<-chA) // @pointsto main.incr
|
||||
print(chB) // @pointsto makechan@c3makeB:13
|
||||
print(<-chB) // @pointsto main.decr | main.chan3$1
|
||||
|
||||
(<-chA)(3)
|
||||
}
|
||||
|
||||
// @calls main.chan3 -> main.incr
|
||||
|
||||
func chan4() {
|
||||
chA := make(chan func(int) int, 0) // @line c4makeA
|
||||
chB := make(chan func(int) int, 0) // @line c4makeB
|
||||
|
||||
select {
|
||||
case chA <- incr:
|
||||
case chB <- decr:
|
||||
case a := <-chA:
|
||||
print(a) // @pointsto main.incr
|
||||
case b := <-chB:
|
||||
print(b) // @pointsto main.decr
|
||||
default:
|
||||
print(chA) // @pointsto makechan@c4makeA:13
|
||||
print(chB) // @pointsto makechan@c4makeB:13
|
||||
}
|
||||
|
||||
for k := range chA {
|
||||
print(k) // @pointsto main.incr
|
||||
}
|
||||
// Exercise constraint generation (regtest for a crash).
|
||||
for range chA {
|
||||
}
|
||||
}
|
||||
|
||||
// Multi-word channel value in select with multiple receive cases.
|
||||
// (Regtest for a crash.)
|
||||
func chan5() {
|
||||
type T struct {
|
||||
x *int
|
||||
y interface{}
|
||||
}
|
||||
ch := make(chan T)
|
||||
ch <- T{new(int), incr} // @line ch5new
|
||||
select {
|
||||
case a := <-ch:
|
||||
print(a.x) // @pointsto new@ch5new:13
|
||||
print(a.y) // @types func(x int) int
|
||||
case b := <-ch:
|
||||
print(b.x) // @pointsto new@ch5new:13
|
||||
print(b.y) // @types func(x int) int
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
chan1()
|
||||
chan2()
|
||||
chan3()
|
||||
chan4()
|
||||
chan5()
|
||||
}
|
85
vendor/golang.org/x/tools/go/pointer/testdata/chanreflect.go
generated
vendored
Normal file
85
vendor/golang.org/x/tools/go/pointer/testdata/chanreflect.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Test of channels with reflection.
|
||||
|
||||
var a, b int
|
||||
|
||||
func chanreflect1() {
|
||||
ch := make(chan *int, 0) // @line cr1make
|
||||
crv := reflect.ValueOf(ch)
|
||||
crv.Send(reflect.ValueOf(&a))
|
||||
print(crv.Interface()) // @types chan *int
|
||||
print(crv.Interface().(chan *int)) // @pointsto makechan@cr1make:12
|
||||
print(<-ch) // @pointsto main.a
|
||||
}
|
||||
|
||||
func chanreflect1i() {
|
||||
// Exercises reflect.Value conversions to/from interfaces:
|
||||
// a different code path than for concrete types.
|
||||
ch := make(chan interface{}, 0)
|
||||
reflect.ValueOf(ch).Send(reflect.ValueOf(&a))
|
||||
v := <-ch
|
||||
print(v) // @types *int
|
||||
print(v.(*int)) // @pointsto main.a
|
||||
}
|
||||
|
||||
func chanreflect2() {
|
||||
ch := make(chan *int, 0)
|
||||
ch <- &b
|
||||
crv := reflect.ValueOf(ch)
|
||||
r, _ := crv.Recv()
|
||||
print(r.Interface()) // @types *int
|
||||
print(r.Interface().(*int)) // @pointsto main.b
|
||||
}
|
||||
|
||||
func chanOfRecv() {
|
||||
// MakeChan(<-chan) is a no-op.
|
||||
t := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(&a))
|
||||
print(reflect.Zero(t).Interface()) // @types <-chan *int
|
||||
print(reflect.MakeChan(t, 0).Interface().(<-chan *int)) // @pointsto
|
||||
print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto
|
||||
}
|
||||
|
||||
func chanOfSend() {
|
||||
// MakeChan(chan<-) is a no-op.
|
||||
t := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(&a))
|
||||
print(reflect.Zero(t).Interface()) // @types chan<- *int
|
||||
print(reflect.MakeChan(t, 0).Interface().(chan<- *int)) // @pointsto
|
||||
print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto
|
||||
}
|
||||
|
||||
func chanOfBoth() {
|
||||
t := reflect.ChanOf(reflect.BothDir, reflect.TypeOf(&a))
|
||||
print(reflect.Zero(t).Interface()) // @types chan *int
|
||||
ch := reflect.MakeChan(t, 0)
|
||||
print(ch.Interface().(chan *int)) // @pointsto <alloc in reflect.MakeChan>
|
||||
ch.Send(reflect.ValueOf(&b))
|
||||
ch.Interface().(chan *int) <- &a
|
||||
r, _ := ch.Recv()
|
||||
print(r.Interface().(*int)) // @pointsto main.a | main.b
|
||||
print(<-ch.Interface().(chan *int)) // @pointsto main.a | main.b
|
||||
}
|
||||
|
||||
var unknownDir reflect.ChanDir // not a constant
|
||||
|
||||
func chanOfUnknown() {
|
||||
// Unknown channel direction: assume all three.
|
||||
// MakeChan only works on the bi-di channel type.
|
||||
t := reflect.ChanOf(unknownDir, reflect.TypeOf(&a))
|
||||
print(reflect.Zero(t).Interface()) // @types <-chan *int | chan<- *int | chan *int
|
||||
print(reflect.MakeChan(t, 0).Interface()) // @types chan *int
|
||||
}
|
||||
|
||||
func main() {
|
||||
chanreflect1()
|
||||
chanreflect1i()
|
||||
chanreflect2()
|
||||
chanOfRecv()
|
||||
chanOfSend()
|
||||
chanOfBoth()
|
||||
chanOfUnknown()
|
||||
}
|
35
vendor/golang.org/x/tools/go/pointer/testdata/chanreflect1.go
generated
vendored
Normal file
35
vendor/golang.org/x/tools/go/pointer/testdata/chanreflect1.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
//
|
||||
// This test is very sensitive to line-number perturbations!
|
||||
|
||||
// Test of channels with reflection.
|
||||
|
||||
var a, b int
|
||||
|
||||
func chanreflect1() {
|
||||
ch := make(chan *int, 0)
|
||||
crv := reflect.ValueOf(ch)
|
||||
crv.Send(reflect.ValueOf(&a))
|
||||
print(crv.Interface()) // @types chan *int
|
||||
print(crv.Interface().(chan *int)) // @pointsto makechan@testdata/chanreflect.go:15:12
|
||||
print(<-ch) // @pointsto main.a
|
||||
}
|
||||
|
||||
func chanreflect2() {
|
||||
ch := make(chan *int, 0)
|
||||
ch <- &b
|
||||
crv := reflect.ValueOf(ch)
|
||||
r, _ := crv.Recv()
|
||||
print(r.Interface()) // @types *int
|
||||
print(r.Interface().(*int)) // @pointsto main.b
|
||||
}
|
||||
|
||||
func main() {
|
||||
chanreflect1()
|
||||
chanreflect2()
|
||||
}
|
48
vendor/golang.org/x/tools/go/pointer/testdata/context.go
generated
vendored
Normal file
48
vendor/golang.org/x/tools/go/pointer/testdata/context.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Test of context-sensitive treatment of certain function calls,
|
||||
// e.g. static calls to simple accessor methods.
|
||||
|
||||
var a, b int
|
||||
|
||||
type T struct{ x *int }
|
||||
|
||||
func (t *T) SetX(x *int) { t.x = x }
|
||||
func (t *T) GetX() *int { return t.x }
|
||||
|
||||
func context1() {
|
||||
var t1, t2 T
|
||||
t1.SetX(&a)
|
||||
t2.SetX(&b)
|
||||
print(t1.GetX()) // @pointsto main.a
|
||||
print(t2.GetX()) // @pointsto main.b
|
||||
}
|
||||
|
||||
func context2() {
|
||||
id := func(x *int) *int {
|
||||
print(x) // @pointsto main.a | main.b
|
||||
return x
|
||||
}
|
||||
print(id(&a)) // @pointsto main.a
|
||||
print(id(&b)) // @pointsto main.b
|
||||
|
||||
// Same again, but anon func has free vars.
|
||||
var c int // @line context2c
|
||||
id2 := func(x *int) (*int, *int) {
|
||||
print(x) // @pointsto main.a | main.b
|
||||
return x, &c
|
||||
}
|
||||
p, q := id2(&a)
|
||||
print(p) // @pointsto main.a
|
||||
print(q) // @pointsto c@context2c:6
|
||||
r, s := id2(&b)
|
||||
print(r) // @pointsto main.b
|
||||
print(s) // @pointsto c@context2c:6
|
||||
}
|
||||
|
||||
func main() {
|
||||
context1()
|
||||
context2()
|
||||
}
|
63
vendor/golang.org/x/tools/go/pointer/testdata/conv.go
generated
vendored
Normal file
63
vendor/golang.org/x/tools/go/pointer/testdata/conv.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "unsafe"
|
||||
|
||||
var a int
|
||||
|
||||
func conv1() {
|
||||
// Conversions of channel direction.
|
||||
ch := make(chan int) // @line c1make
|
||||
print((<-chan int)(ch)) // @pointsto makechan@c1make:12
|
||||
print((chan<- int)(ch)) // @pointsto makechan@c1make:12
|
||||
}
|
||||
|
||||
func conv2() {
|
||||
// string -> []byte/[]rune conversion
|
||||
s := "foo"
|
||||
ba := []byte(s) // @line c2ba
|
||||
ra := []rune(s) // @line c2ra
|
||||
print(ba) // @pointsto convert@c2ba:14
|
||||
print(ra) // @pointsto convert@c2ra:14
|
||||
}
|
||||
|
||||
func conv3() {
|
||||
// Conversion of same underlying types.
|
||||
type PI *int
|
||||
pi := PI(&a)
|
||||
print(pi) // @pointsto main.a
|
||||
|
||||
pint := (*int)(pi)
|
||||
print(pint) // @pointsto main.a
|
||||
|
||||
// Conversions between pointers to identical base types.
|
||||
var y *PI = &pi
|
||||
var x **int = (**int)(y)
|
||||
print(*x) // @pointsto main.a
|
||||
print(*y) // @pointsto main.a
|
||||
y = (*PI)(x)
|
||||
print(*y) // @pointsto main.a
|
||||
}
|
||||
|
||||
func conv4() {
|
||||
// Handling of unsafe.Pointer conversion is unsound:
|
||||
// we lose the alias to main.a and get something like new(int) instead.
|
||||
p := (*int)(unsafe.Pointer(&a)) // @line c2p
|
||||
print(p) // @pointsto convert@c2p:13
|
||||
}
|
||||
|
||||
// Regression test for b/8231.
|
||||
func conv5() {
|
||||
type P unsafe.Pointer
|
||||
var i *struct{}
|
||||
_ = P(i)
|
||||
}
|
||||
|
||||
func main() {
|
||||
conv1()
|
||||
conv2()
|
||||
conv3()
|
||||
conv4()
|
||||
conv5()
|
||||
}
|
21
vendor/golang.org/x/tools/go/pointer/testdata/extended.go
generated
vendored
Normal file
21
vendor/golang.org/x/tools/go/pointer/testdata/extended.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var a int
|
||||
|
||||
type t struct {
|
||||
a *map[string]chan *int
|
||||
}
|
||||
|
||||
func fn() []t {
|
||||
m := make(map[string]chan *int)
|
||||
m[""] = make(chan *int, 1)
|
||||
m[""] <- &a
|
||||
return []t{t{a: &m}}
|
||||
}
|
||||
|
||||
func main() {
|
||||
x := fn()
|
||||
print(x) // @pointstoquery <-(*x[i].a)[key] main.a
|
||||
}
|
89
vendor/golang.org/x/tools/go/pointer/testdata/finalizer.go
generated
vendored
Normal file
89
vendor/golang.org/x/tools/go/pointer/testdata/finalizer.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import "runtime"
|
||||
|
||||
func final1a(x *int) int {
|
||||
print(x) // @pointsto new@newint:10
|
||||
return *x
|
||||
}
|
||||
|
||||
func final1b(x *bool) {
|
||||
print(x) // @pointsto
|
||||
}
|
||||
|
||||
func runtimeSetFinalizer1() {
|
||||
x := new(int) // @line newint
|
||||
runtime.SetFinalizer(x, final1a) // ok: final1a's result is ignored
|
||||
runtime.SetFinalizer(x, final1b) // param type mismatch: no effect
|
||||
}
|
||||
|
||||
// @calls main.runtimeSetFinalizer1 -> main.final1a
|
||||
// @calls main.runtimeSetFinalizer1 -> main.final1b
|
||||
|
||||
func final2a(x *bool) {
|
||||
print(x) // @pointsto new@newbool1:10 | new@newbool2:10
|
||||
}
|
||||
|
||||
func final2b(x *bool) {
|
||||
print(x) // @pointsto new@newbool1:10 | new@newbool2:10
|
||||
}
|
||||
|
||||
func runtimeSetFinalizer2() {
|
||||
x := new(bool) // @line newbool1
|
||||
f := final2a
|
||||
if unknown {
|
||||
x = new(bool) // @line newbool2
|
||||
f = final2b
|
||||
}
|
||||
runtime.SetFinalizer(x, f)
|
||||
}
|
||||
|
||||
// @calls main.runtimeSetFinalizer2 -> main.final2a
|
||||
// @calls main.runtimeSetFinalizer2 -> main.final2b
|
||||
|
||||
type T int
|
||||
|
||||
func (t *T) finalize() {
|
||||
print(t) // @pointsto new@final3:10
|
||||
}
|
||||
|
||||
func runtimeSetFinalizer3() {
|
||||
x := new(T) // @line final3
|
||||
runtime.SetFinalizer(x, (*T).finalize)
|
||||
}
|
||||
|
||||
// @calls main.runtimeSetFinalizer3 -> (*main.T).finalize$thunk
|
||||
|
||||
// I hope I never live to see this code in the wild.
|
||||
var setFinalizer = runtime.SetFinalizer
|
||||
|
||||
func final4(x *int) {
|
||||
print(x) // @pointsto new@finalIndirect:10
|
||||
}
|
||||
|
||||
func runtimeSetFinalizerIndirect() {
|
||||
// In an indirect call, the shared contour for SetFinalizer is
|
||||
// used, i.e. the call is not inlined and appears in the call graph.
|
||||
x := new(int) // @line finalIndirect
|
||||
setFinalizer(x, final4)
|
||||
}
|
||||
|
||||
// Exercise the elimination of SetFinalizer
|
||||
// constraints with non-pointer operands.
|
||||
func runtimeSetFinalizerNonpointer() {
|
||||
runtime.SetFinalizer(nil, (*T).finalize) // x is a non-pointer
|
||||
runtime.SetFinalizer((*T).finalize, nil) // f is a non-pointer
|
||||
}
|
||||
|
||||
// @calls main.runtimeSetFinalizerIndirect -> runtime.SetFinalizer
|
||||
// @calls runtime.SetFinalizer -> main.final4
|
||||
|
||||
func main() {
|
||||
runtimeSetFinalizer1()
|
||||
runtimeSetFinalizer2()
|
||||
runtimeSetFinalizer3()
|
||||
runtimeSetFinalizerIndirect()
|
||||
runtimeSetFinalizerNonpointer()
|
||||
}
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
63
vendor/golang.org/x/tools/go/pointer/testdata/flow.go
generated
vendored
Normal file
63
vendor/golang.org/x/tools/go/pointer/testdata/flow.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Demonstration of directionality of flow edges.
|
||||
|
||||
func f1() {}
|
||||
func f2() {}
|
||||
|
||||
var somepred bool
|
||||
|
||||
// Tracking functions.
|
||||
func flow1() {
|
||||
s := f1
|
||||
p := f2
|
||||
q := p
|
||||
r := q
|
||||
if somepred {
|
||||
r = s
|
||||
}
|
||||
print(s) // @pointsto main.f1
|
||||
print(p) // @pointsto main.f2
|
||||
print(q) // @pointsto main.f2
|
||||
print(r) // @pointsto main.f1 | main.f2
|
||||
}
|
||||
|
||||
// Tracking concrete types in interfaces.
|
||||
func flow2() {
|
||||
var s interface{} = 1
|
||||
var p interface{} = "foo"
|
||||
q := p
|
||||
r := q
|
||||
if somepred {
|
||||
r = s
|
||||
}
|
||||
print(s) // @types int
|
||||
print(p) // @types string
|
||||
print(q) // @types string
|
||||
print(r) // @types int | string
|
||||
}
|
||||
|
||||
var g1, g2 int
|
||||
|
||||
// Tracking addresses of globals.
|
||||
func flow3() {
|
||||
s := &g1
|
||||
p := &g2
|
||||
q := p
|
||||
r := q
|
||||
if somepred {
|
||||
r = s
|
||||
}
|
||||
print(s) // @pointsto main.g1
|
||||
print(p) // @pointsto main.g2
|
||||
print(q) // @pointsto main.g2
|
||||
print(r) // @pointsto main.g2 | main.g1
|
||||
}
|
||||
|
||||
func main() {
|
||||
flow1()
|
||||
flow2()
|
||||
flow3()
|
||||
}
|
42
vendor/golang.org/x/tools/go/pointer/testdata/fmtexcerpt.go
generated
vendored
Normal file
42
vendor/golang.org/x/tools/go/pointer/testdata/fmtexcerpt.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// +build ignore
|
||||
|
||||
// This is a slice of the fmt package.
|
||||
|
||||
package main
|
||||
|
||||
type pp struct {
|
||||
field interface{}
|
||||
}
|
||||
|
||||
func newPrinter() *pp {
|
||||
return new(pp)
|
||||
}
|
||||
|
||||
func Fprintln(a ...interface{}) {
|
||||
p := newPrinter()
|
||||
p.doPrint(a, true, true)
|
||||
}
|
||||
|
||||
func Println(a ...interface{}) {
|
||||
Fprintln(a...)
|
||||
}
|
||||
|
||||
func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
|
||||
print(a[0]) // @types S | string
|
||||
stringer := a[0].(interface {
|
||||
String() string
|
||||
})
|
||||
|
||||
stringer.String()
|
||||
print(stringer) // @types S
|
||||
}
|
||||
|
||||
type S int
|
||||
|
||||
func (S) String() string { return "" }
|
||||
|
||||
func main() {
|
||||
Println("Hello, World!", S(0))
|
||||
}
|
||||
|
||||
// @calls (*main.pp).doPrint -> (main.S).String
|
205
vendor/golang.org/x/tools/go/pointer/testdata/func.go
generated
vendored
Normal file
205
vendor/golang.org/x/tools/go/pointer/testdata/func.go
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var a, b, c int
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
||||
|
||||
func func1() {
|
||||
var h int // @line f1h
|
||||
f := func(x *int) *int {
|
||||
if unknown {
|
||||
return &b
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// FV(g) = {f, h}
|
||||
g := func(x *int) *int {
|
||||
if unknown {
|
||||
return &h
|
||||
}
|
||||
return f(x)
|
||||
}
|
||||
|
||||
print(g(&a)) // @pointsto main.a | main.b | h@f1h:6
|
||||
print(f(&a)) // @pointsto main.a | main.b
|
||||
print(&a) // @pointsto main.a
|
||||
}
|
||||
|
||||
// @calls main.func1 -> main.func1$2
|
||||
// @calls main.func1 -> main.func1$1
|
||||
// @calls main.func1$2 -> main.func1$1
|
||||
|
||||
func func2() {
|
||||
var x, y *int
|
||||
defer func() {
|
||||
x = &a
|
||||
}()
|
||||
go func() {
|
||||
y = &b
|
||||
}()
|
||||
print(x) // @pointsto main.a
|
||||
print(y) // @pointsto main.b
|
||||
}
|
||||
|
||||
func func3() {
|
||||
x, y := func() (x, y *int) {
|
||||
x = &a
|
||||
y = &b
|
||||
if unknown {
|
||||
return nil, &c
|
||||
}
|
||||
return
|
||||
}()
|
||||
print(x) // @pointsto main.a
|
||||
print(y) // @pointsto main.b | main.c
|
||||
}
|
||||
|
||||
func swap(x, y *int) (*int, *int) { // @line swap
|
||||
print(&x) // @pointsto x@swap:11
|
||||
print(x) // @pointsto makeslice[*]@func4make:11
|
||||
print(&y) // @pointsto y@swap:14
|
||||
print(y) // @pointsto j@f4j:5
|
||||
return y, x
|
||||
}
|
||||
|
||||
func func4() {
|
||||
a := make([]int, 10) // @line func4make
|
||||
i, j := 123, 456 // @line f4j
|
||||
_ = i
|
||||
p, q := swap(&a[3], &j)
|
||||
print(p) // @pointsto j@f4j:5
|
||||
print(q) // @pointsto makeslice[*]@func4make:11
|
||||
|
||||
f := &b
|
||||
print(f) // @pointsto main.b
|
||||
}
|
||||
|
||||
type T int
|
||||
|
||||
func (t *T) f(x *int) *int {
|
||||
print(t) // @pointsto main.a
|
||||
print(x) // @pointsto main.c
|
||||
return &b
|
||||
}
|
||||
|
||||
func (t *T) g(x *int) *int {
|
||||
print(t) // @pointsto main.a
|
||||
print(x) // @pointsto main.b
|
||||
return &c
|
||||
}
|
||||
|
||||
func (t *T) h(x *int) *int {
|
||||
print(t) // @pointsto main.a
|
||||
print(x) // @pointsto main.b
|
||||
return &c
|
||||
}
|
||||
|
||||
var h func(*T, *int) *int
|
||||
|
||||
func func5() {
|
||||
// Static call of method.
|
||||
t := (*T)(&a)
|
||||
print(t.f(&c)) // @pointsto main.b
|
||||
|
||||
// Static call of method as function
|
||||
print((*T).g(t, &b)) // @pointsto main.c
|
||||
|
||||
// Dynamic call (not invoke) of method.
|
||||
h = (*T).h
|
||||
print(h(t, &b)) // @pointsto main.c
|
||||
}
|
||||
|
||||
// @calls main.func5 -> (*main.T).f
|
||||
// @calls main.func5 -> (*main.T).g$thunk
|
||||
// @calls main.func5 -> (*main.T).h$thunk
|
||||
|
||||
func func6() {
|
||||
A := &a
|
||||
f := func() *int {
|
||||
return A // (free variable)
|
||||
}
|
||||
print(f()) // @pointsto main.a
|
||||
}
|
||||
|
||||
// @calls main.func6 -> main.func6$1
|
||||
|
||||
type I interface {
|
||||
f()
|
||||
}
|
||||
|
||||
type D struct{}
|
||||
|
||||
func (D) f() {}
|
||||
|
||||
func func7() {
|
||||
var i I = D{}
|
||||
imethodClosure := i.f
|
||||
imethodClosure()
|
||||
// @calls main.func7 -> (main.I).f$bound
|
||||
// @calls (main.I).f$bound -> (main.D).f
|
||||
|
||||
var d D
|
||||
cmethodClosure := d.f
|
||||
cmethodClosure()
|
||||
// @calls main.func7 -> (main.D).f$bound
|
||||
// @calls (main.D).f$bound ->(main.D).f
|
||||
|
||||
methodExpr := D.f
|
||||
methodExpr(d)
|
||||
// @calls main.func7 -> (main.D).f$thunk
|
||||
}
|
||||
|
||||
func func8(x ...int) {
|
||||
print(&x[0]) // @pointsto varargs[*]@varargs:15
|
||||
}
|
||||
|
||||
type E struct {
|
||||
x1, x2, x3, x4, x5 *int
|
||||
}
|
||||
|
||||
func (e E) f() {}
|
||||
|
||||
func func9() {
|
||||
// Regression test for bug reported by Jon Valdes on golang-dev, Jun 19 2014.
|
||||
// The receiver of a bound method closure may be of a multi-node type, E.
|
||||
// valueNode was reserving only a single node for it, so the
|
||||
// nodes used by the immediately following constraints
|
||||
// (e.g. param 'i') would get clobbered.
|
||||
|
||||
var e E
|
||||
e.x1 = &a
|
||||
e.x2 = &a
|
||||
e.x3 = &a
|
||||
e.x4 = &a
|
||||
e.x5 = &a
|
||||
|
||||
_ = e.f // form a closure---must reserve sizeof(E) nodes
|
||||
|
||||
func(i I) {
|
||||
i.f() // must not crash the solver
|
||||
}(new(D))
|
||||
|
||||
print(e.x1) // @pointsto main.a
|
||||
print(e.x2) // @pointsto main.a
|
||||
print(e.x3) // @pointsto main.a
|
||||
print(e.x4) // @pointsto main.a
|
||||
print(e.x5) // @pointsto main.a
|
||||
}
|
||||
|
||||
func main() {
|
||||
func1()
|
||||
func2()
|
||||
func3()
|
||||
func4()
|
||||
func5()
|
||||
func6()
|
||||
func7()
|
||||
func8(1, 2, 3) // @line varargs
|
||||
func9()
|
||||
}
|
||||
|
||||
// @calls <root> -> main.main
|
||||
// @calls <root> -> main.init
|
130
vendor/golang.org/x/tools/go/pointer/testdata/funcreflect.go
generated
vendored
Normal file
130
vendor/golang.org/x/tools/go/pointer/testdata/funcreflect.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
var zero, a, b int
|
||||
var false2 bool
|
||||
|
||||
func f(p *int, q hasF) *int {
|
||||
print(p) // @pointsto main.a
|
||||
print(q) // @types *T
|
||||
print(q.(*T)) // @pointsto new@newT1:22
|
||||
return &b
|
||||
}
|
||||
|
||||
func g(p *bool) (*int, *bool, hasF) {
|
||||
return &b, p, new(T) // @line newT2
|
||||
}
|
||||
|
||||
func reflectValueCall() {
|
||||
rvf := reflect.ValueOf(f)
|
||||
res := rvf.Call([]reflect.Value{
|
||||
// argument order is not significant:
|
||||
reflect.ValueOf(new(T)), // @line newT1
|
||||
reflect.ValueOf(&a),
|
||||
})
|
||||
print(res[0].Interface()) // @types *int
|
||||
print(res[0].Interface().(*int)) // @pointsto main.b
|
||||
}
|
||||
|
||||
// @calls main.reflectValueCall -> main.f
|
||||
|
||||
func reflectValueCallIndirect() {
|
||||
rvf := reflect.ValueOf(g)
|
||||
call := rvf.Call // kids, don't try this at home
|
||||
|
||||
// Indirect call uses shared contour.
|
||||
//
|
||||
// Also notice that argument position doesn't matter, and args
|
||||
// of inappropriate type (e.g. 'a') are ignored.
|
||||
res := call([]reflect.Value{
|
||||
reflect.ValueOf(&a),
|
||||
reflect.ValueOf(&false2),
|
||||
})
|
||||
res0 := res[0].Interface()
|
||||
print(res0) // @types *int | *bool | *T
|
||||
print(res0.(*int)) // @pointsto main.b
|
||||
print(res0.(*bool)) // @pointsto main.false2
|
||||
print(res0.(hasF)) // @types *T
|
||||
print(res0.(*T)) // @pointsto new@newT2:19
|
||||
}
|
||||
|
||||
// @calls main.reflectValueCallIndirect -> (reflect.Value).Call$bound
|
||||
// @calls (reflect.Value).Call$bound -> main.g
|
||||
|
||||
func reflectTypeInOut() {
|
||||
var f func(float64, bool) (string, int)
|
||||
print(reflect.Zero(reflect.TypeOf(f).In(0)).Interface()) // @types float64
|
||||
print(reflect.Zero(reflect.TypeOf(f).In(1)).Interface()) // @types bool
|
||||
print(reflect.Zero(reflect.TypeOf(f).In(-1)).Interface()) // @types float64 | bool
|
||||
print(reflect.Zero(reflect.TypeOf(f).In(zero)).Interface()) // @types float64 | bool
|
||||
|
||||
print(reflect.Zero(reflect.TypeOf(f).Out(0)).Interface()) // @types string
|
||||
print(reflect.Zero(reflect.TypeOf(f).Out(1)).Interface()) // @types int
|
||||
print(reflect.Zero(reflect.TypeOf(f).Out(2)).Interface()) // @types
|
||||
|
||||
print(reflect.Zero(reflect.TypeOf(3).Out(0)).Interface()) // @types
|
||||
}
|
||||
|
||||
type hasF interface {
|
||||
F()
|
||||
}
|
||||
|
||||
type T struct{}
|
||||
|
||||
func (T) F() {}
|
||||
func (T) g(int) {}
|
||||
|
||||
type U struct{}
|
||||
|
||||
func (U) F(int) {}
|
||||
func (U) g(string) {}
|
||||
|
||||
type I interface {
|
||||
f()
|
||||
}
|
||||
|
||||
var nonconst string
|
||||
|
||||
func reflectTypeMethodByName() {
|
||||
TU := reflect.TypeOf([]interface{}{T{}, U{}}[0])
|
||||
print(reflect.Zero(TU)) // @types T | U
|
||||
|
||||
F, _ := TU.MethodByName("F")
|
||||
print(reflect.Zero(F.Type)) // @types func(T) | func(U, int)
|
||||
print(F.Func) // @pointsto (main.T).F | (main.U).F
|
||||
|
||||
g, _ := TU.MethodByName("g")
|
||||
print(reflect.Zero(g.Type)) // @types func(T, int) | func(U, string)
|
||||
print(g.Func) // @pointsto (main.T).g | (main.U).g
|
||||
|
||||
// Non-literal method names are treated less precisely.
|
||||
U := reflect.TypeOf(U{})
|
||||
X, _ := U.MethodByName(nonconst)
|
||||
print(reflect.Zero(X.Type)) // @types func(U, int) | func(U, string)
|
||||
print(X.Func) // @pointsto (main.U).F | (main.U).g
|
||||
|
||||
// Interface methods.
|
||||
rThasF := reflect.TypeOf(new(hasF)).Elem()
|
||||
print(reflect.Zero(rThasF)) // @types hasF
|
||||
F2, _ := rThasF.MethodByName("F")
|
||||
print(reflect.Zero(F2.Type)) // @types func()
|
||||
print(F2.Func) // @pointsto
|
||||
|
||||
}
|
||||
|
||||
func reflectTypeMethod() {
|
||||
m := reflect.TypeOf(T{}).Method(0)
|
||||
print(reflect.Zero(m.Type)) // @types func(T) | func(T, int)
|
||||
print(m.Func) // @pointsto (main.T).F | (main.T).g
|
||||
}
|
||||
|
||||
func main() {
|
||||
reflectValueCall()
|
||||
reflectValueCallIndirect()
|
||||
reflectTypeInOut()
|
||||
reflectTypeMethodByName()
|
||||
reflectTypeMethod()
|
||||
}
|
27
vendor/golang.org/x/tools/go/pointer/testdata/hello.go
generated
vendored
Normal file
27
vendor/golang.org/x/tools/go/pointer/testdata/hello.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type S int
|
||||
|
||||
var theS S
|
||||
|
||||
func (s *S) String() string {
|
||||
print(s) // @pointsto main.theS
|
||||
return ""
|
||||
}
|
||||
|
||||
func main() {
|
||||
// os.Args is considered intrinsically allocated,
|
||||
// but may also be set explicitly (e.g. on Windows), hence '...'.
|
||||
print(os.Args) // @pointsto <command-line args> | ...
|
||||
fmt.Println("Hello, World!", &theS)
|
||||
}
|
||||
|
||||
// @calls main.main -> fmt.Println
|
||||
// @calls (*fmt.pp).handleMethods -> (*main.S).String
|
152
vendor/golang.org/x/tools/go/pointer/testdata/interfaces.go
generated
vendored
Normal file
152
vendor/golang.org/x/tools/go/pointer/testdata/interfaces.go
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
type I interface {
|
||||
f()
|
||||
}
|
||||
|
||||
type C int
|
||||
|
||||
func (*C) f() {}
|
||||
|
||||
type D struct{ ptr *int }
|
||||
|
||||
func (D) f() {}
|
||||
|
||||
type E struct{}
|
||||
|
||||
func (*E) f() {}
|
||||
|
||||
var a, b int
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
||||
|
||||
func interface1() {
|
||||
var i interface{} = &a
|
||||
var j interface{} = D{&b}
|
||||
k := j
|
||||
if unknown {
|
||||
k = i
|
||||
}
|
||||
|
||||
print(i) // @types *int
|
||||
print(j) // @types D
|
||||
print(k) // @types *int | D
|
||||
|
||||
print(i.(*int)) // @pointsto main.a
|
||||
print(j.(*int)) // @pointsto
|
||||
print(k.(*int)) // @pointsto main.a
|
||||
|
||||
print(i.(D).ptr) // @pointsto
|
||||
print(j.(D).ptr) // @pointsto main.b
|
||||
print(k.(D).ptr) // @pointsto main.b
|
||||
}
|
||||
|
||||
func interface2() {
|
||||
var i I = (*C)(&a)
|
||||
var j I = D{&a}
|
||||
k := j
|
||||
if unknown {
|
||||
k = i
|
||||
}
|
||||
|
||||
print(i) // @types *C
|
||||
print(j) // @types D
|
||||
print(k) // @types *C | D
|
||||
print(k) // @pointsto makeinterface:main.D | makeinterface:*main.C
|
||||
|
||||
k.f()
|
||||
// @calls main.interface2 -> (*main.C).f
|
||||
// @calls main.interface2 -> (main.D).f
|
||||
|
||||
print(i.(*C)) // @pointsto main.a
|
||||
print(j.(D).ptr) // @pointsto main.a
|
||||
print(k.(*C)) // @pointsto main.a
|
||||
|
||||
switch x := k.(type) {
|
||||
case *C:
|
||||
print(x) // @pointsto main.a
|
||||
case D:
|
||||
print(x.ptr) // @pointsto main.a
|
||||
case *E:
|
||||
print(x) // @pointsto
|
||||
}
|
||||
}
|
||||
|
||||
func interface3() {
|
||||
// There should be no backflow of concrete types from the type-switch to x.
|
||||
var x interface{} = 0
|
||||
print(x) // @types int
|
||||
switch x.(type) {
|
||||
case int:
|
||||
case string:
|
||||
}
|
||||
}
|
||||
|
||||
func interface4() {
|
||||
var i interface{} = D{&a}
|
||||
if unknown {
|
||||
i = 123
|
||||
}
|
||||
|
||||
print(i) // @types int | D
|
||||
|
||||
j := i.(I) // interface narrowing type-assertion
|
||||
print(j) // @types D
|
||||
print(j.(D).ptr) // @pointsto main.a
|
||||
|
||||
var l interface{} = j // interface widening assignment.
|
||||
print(l) // @types D
|
||||
print(l.(D).ptr) // @pointsto main.a
|
||||
|
||||
m := j.(interface{}) // interface widening type-assertion.
|
||||
print(m) // @types D
|
||||
print(m.(D).ptr) // @pointsto main.a
|
||||
}
|
||||
|
||||
// Interface method calls and value flow:
|
||||
|
||||
type J interface {
|
||||
f(*int) *int
|
||||
}
|
||||
|
||||
type P struct {
|
||||
x int
|
||||
}
|
||||
|
||||
func (p *P) f(pi *int) *int {
|
||||
print(p) // @pointsto p@i5p:6
|
||||
print(pi) // @pointsto i@i5i:6
|
||||
return &p.x
|
||||
}
|
||||
|
||||
func interface5() {
|
||||
var p P // @line i5p
|
||||
var j J = &p
|
||||
var i int // @line i5i
|
||||
print(j.f(&i)) // @pointsto p.x@i5p:6
|
||||
print(&i) // @pointsto i@i5i:6
|
||||
|
||||
print(j) // @pointsto makeinterface:*main.P
|
||||
}
|
||||
|
||||
// @calls main.interface5 -> (*main.P).f
|
||||
|
||||
func interface6() {
|
||||
f := I.f
|
||||
print(f) // @pointsto (main.I).f$thunk
|
||||
f(new(struct{ D }))
|
||||
}
|
||||
|
||||
// @calls main.interface6 -> (main.I).f$thunk
|
||||
// @calls (main.I).f$thunk -> (*struct{main.D}).f
|
||||
|
||||
func main() {
|
||||
interface1()
|
||||
interface2()
|
||||
interface3()
|
||||
interface4()
|
||||
interface5()
|
||||
interface6()
|
||||
}
|
17
vendor/golang.org/x/tools/go/pointer/testdata/issue9002.go
generated
vendored
Normal file
17
vendor/golang.org/x/tools/go/pointer/testdata/issue9002.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
// Regression test for golang issue 9002.
|
||||
//
|
||||
// The two-result "value,ok" receive operation generated a
|
||||
// too-wide constraint loading (value int, ok bool), not bool,
|
||||
// from the channel.
|
||||
//
|
||||
// This bug manifested itself in an out-of-bounds array access
|
||||
// when the makechan object was the highest-numbered node, as in
|
||||
// this program.
|
||||
//
|
||||
// In more realistic programs it silently resulted in bogus
|
||||
// constraints.
|
||||
_, _ = <-make(chan int)
|
||||
}
|
117
vendor/golang.org/x/tools/go/pointer/testdata/mapreflect.go
generated
vendored
Normal file
117
vendor/golang.org/x/tools/go/pointer/testdata/mapreflect.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Test of maps with reflection.
|
||||
|
||||
import "reflect"
|
||||
|
||||
var a int
|
||||
var b bool
|
||||
|
||||
func reflectMapKeysIndex() {
|
||||
m := make(map[*int]*bool) // @line mr1make
|
||||
m[&a] = &b
|
||||
|
||||
mrv := reflect.ValueOf(m)
|
||||
print(mrv.Interface()) // @types map[*int]*bool
|
||||
print(mrv.Interface().(map[*int]*bool)) // @pointsto makemap@mr1make:11
|
||||
print(mrv) // @pointsto makeinterface:map[*int]*bool
|
||||
print(mrv) // @types map[*int]*bool
|
||||
|
||||
keys := mrv.MapKeys()
|
||||
print(keys) // @pointsto <alloc in (reflect.Value).MapKeys>
|
||||
for _, k := range keys {
|
||||
print(k) // @pointsto <alloc in (reflect.Value).MapKeys>
|
||||
print(k) // @types *int
|
||||
print(k.Interface()) // @types *int
|
||||
print(k.Interface().(*int)) // @pointsto main.a
|
||||
|
||||
v := mrv.MapIndex(k)
|
||||
print(v.Interface()) // @types *bool
|
||||
print(v.Interface().(*bool)) // @pointsto main.b
|
||||
}
|
||||
}
|
||||
|
||||
func reflectSetMapIndex() {
|
||||
m := make(map[*int]*bool)
|
||||
mrv := reflect.ValueOf(m)
|
||||
mrv.SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b))
|
||||
|
||||
print(m[nil]) // @pointsto main.b
|
||||
|
||||
for _, k := range mrv.MapKeys() {
|
||||
print(k.Interface()) // @types *int
|
||||
print(k.Interface().(*int)) // @pointsto main.a
|
||||
}
|
||||
|
||||
tmap := reflect.TypeOf(m)
|
||||
// types.EvalNode won't let us refer to non-exported types:
|
||||
// print(tmap) // #@types *reflect.rtype
|
||||
print(tmap) // @pointsto map[*int]*bool
|
||||
|
||||
zmap := reflect.Zero(tmap)
|
||||
print(zmap) // @pointsto <alloc in reflect.Zero>
|
||||
print(zmap.Interface()) // @pointsto <alloc in reflect.Zero>
|
||||
|
||||
print(tmap.Key()) // @pointsto *int
|
||||
print(tmap.Elem()) // @pointsto *bool
|
||||
print(reflect.Zero(tmap.Key())) // @pointsto <alloc in reflect.Zero>
|
||||
print(reflect.Zero(tmap.Key()).Interface()) // @pointsto <alloc in reflect.Zero>
|
||||
print(reflect.Zero(tmap.Key()).Interface()) // @types *int
|
||||
print(reflect.Zero(tmap.Elem())) // @pointsto <alloc in reflect.Zero>
|
||||
print(reflect.Zero(tmap.Elem()).Interface()) // @pointsto <alloc in reflect.Zero>
|
||||
print(reflect.Zero(tmap.Elem()).Interface()) // @types *bool
|
||||
}
|
||||
|
||||
func reflectSetMapIndexInterface() {
|
||||
// Exercises reflect.Value conversions to/from interfaces:
|
||||
// a different code path than for concrete types.
|
||||
m := make(map[interface{}]interface{})
|
||||
reflect.ValueOf(m).SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b))
|
||||
for k, v := range m {
|
||||
print(k) // @types *int
|
||||
print(k.(*int)) // @pointsto main.a
|
||||
print(v) // @types *bool
|
||||
print(v.(*bool)) // @pointsto main.b
|
||||
}
|
||||
}
|
||||
|
||||
func reflectSetMapIndexAssignable() {
|
||||
// SetMapIndex performs implicit assignability conversions.
|
||||
type I *int
|
||||
type J *int
|
||||
|
||||
str := reflect.ValueOf("")
|
||||
|
||||
// *int is assignable to I.
|
||||
m1 := make(map[string]I)
|
||||
reflect.ValueOf(m1).SetMapIndex(str, reflect.ValueOf(new(int))) // @line int
|
||||
print(m1[""]) // @pointsto new@int:58
|
||||
|
||||
// I is assignable to I.
|
||||
m2 := make(map[string]I)
|
||||
reflect.ValueOf(m2).SetMapIndex(str, reflect.ValueOf(I(new(int)))) // @line I
|
||||
print(m2[""]) // @pointsto new@I:60
|
||||
|
||||
// J is not assignable to I.
|
||||
m3 := make(map[string]I)
|
||||
reflect.ValueOf(m3).SetMapIndex(str, reflect.ValueOf(J(new(int))))
|
||||
print(m3[""]) // @pointsto
|
||||
}
|
||||
|
||||
func reflectMakeMap() {
|
||||
t := reflect.TypeOf(map[*int]*bool(nil))
|
||||
v := reflect.MakeMap(t)
|
||||
print(v) // @types map[*int]*bool
|
||||
print(v) // @pointsto <alloc in reflect.MakeMap>
|
||||
}
|
||||
|
||||
func main() {
|
||||
reflectMapKeysIndex()
|
||||
reflectSetMapIndex()
|
||||
reflectSetMapIndexInterface()
|
||||
reflectSetMapIndexAssignable()
|
||||
reflectMakeMap()
|
||||
// TODO(adonovan): reflect.MapOf(Type)
|
||||
}
|
74
vendor/golang.org/x/tools/go/pointer/testdata/maps.go
generated
vendored
Normal file
74
vendor/golang.org/x/tools/go/pointer/testdata/maps.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Test of maps.
|
||||
|
||||
var a, b, c int
|
||||
|
||||
func maps1() {
|
||||
m1 := map[*int]*int{&a: &b} // @line m1m1
|
||||
m2 := make(map[*int]*int) // @line m1m2
|
||||
m2[&b] = &a
|
||||
|
||||
print(m1[nil]) // @pointsto main.b | main.c
|
||||
print(m2[nil]) // @pointsto main.a
|
||||
|
||||
print(m1) // @pointsto makemap@m1m1:21
|
||||
print(m2) // @pointsto makemap@m1m2:12
|
||||
|
||||
m1[&b] = &c
|
||||
|
||||
for k, v := range m1 {
|
||||
print(k) // @pointsto main.a | main.b
|
||||
print(v) // @pointsto main.b | main.c
|
||||
}
|
||||
|
||||
for k, v := range m2 {
|
||||
print(k) // @pointsto main.b
|
||||
print(v) // @pointsto main.a
|
||||
}
|
||||
|
||||
// Lookup doesn't create any aliases.
|
||||
print(m2[&c]) // @pointsto main.a
|
||||
if _, ok := m2[&a]; ok {
|
||||
print(m2[&c]) // @pointsto main.a
|
||||
}
|
||||
}
|
||||
|
||||
func maps2() {
|
||||
m1 := map[*int]*int{&a: &b}
|
||||
m2 := map[*int]*int{&b: &c}
|
||||
_ = []map[*int]*int{m1, m2} // (no spurious merging of m1, m2)
|
||||
|
||||
print(m1[nil]) // @pointsto main.b
|
||||
print(m2[nil]) // @pointsto main.c
|
||||
}
|
||||
|
||||
var g int
|
||||
|
||||
func maps3() {
|
||||
// Regression test for a constraint generation bug for map range
|
||||
// loops in which the key is unused: the (ok, k, v) tuple
|
||||
// returned by ssa.Next may have type 'invalid' for the k and/or
|
||||
// v components, so copying the map key or value may cause
|
||||
// miswiring if the key has >1 components. In the worst case,
|
||||
// this causes a crash. The test below used to report that
|
||||
// pts(v) includes not just main.g but new(float64) too, which
|
||||
// is ill-typed.
|
||||
|
||||
// sizeof(K) > 1, abstractly
|
||||
type K struct{ a, b *float64 }
|
||||
k := K{new(float64), nil}
|
||||
m := map[K]*int{k: &g}
|
||||
|
||||
for _, v := range m {
|
||||
print(v) // @pointsto main.g
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
maps1()
|
||||
maps2()
|
||||
maps3()
|
||||
}
|
36
vendor/golang.org/x/tools/go/pointer/testdata/panic.go
generated
vendored
Normal file
36
vendor/golang.org/x/tools/go/pointer/testdata/panic.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Test of value flow from panic() to recover().
|
||||
// We model them as stores/loads of a global location.
|
||||
// We ignore concrete panic types originating from the runtime.
|
||||
|
||||
var someval int
|
||||
|
||||
type myPanic struct{}
|
||||
|
||||
func f(int) {}
|
||||
|
||||
func g() string { return "" }
|
||||
|
||||
func deadcode() {
|
||||
panic(123) // not reached
|
||||
}
|
||||
|
||||
func main() {
|
||||
switch someval {
|
||||
case 0:
|
||||
panic("oops")
|
||||
case 1:
|
||||
panic(myPanic{})
|
||||
case 2:
|
||||
panic(f)
|
||||
case 3:
|
||||
panic(g)
|
||||
}
|
||||
ex := recover()
|
||||
print(ex) // @types myPanic | string | func(int) | func() string
|
||||
print(ex.(func(int))) // @pointsto main.f
|
||||
print(ex.(func() string)) // @pointsto main.g
|
||||
}
|
11
vendor/golang.org/x/tools/go/pointer/testdata/recur.go
generated
vendored
Normal file
11
vendor/golang.org/x/tools/go/pointer/testdata/recur.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
// Analysis abstraction of recursive calls is finite.
|
||||
|
||||
func main() {
|
||||
main()
|
||||
}
|
||||
|
||||
// @calls main.main -> main.main
|
115
vendor/golang.org/x/tools/go/pointer/testdata/reflect.go
generated
vendored
Normal file
115
vendor/golang.org/x/tools/go/pointer/testdata/reflect.go
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
import "unsafe"
|
||||
|
||||
var a, b int
|
||||
var unknown bool
|
||||
|
||||
func reflectIndirect() {
|
||||
ptr := &a
|
||||
// Pointer:
|
||||
print(reflect.Indirect(reflect.ValueOf(&ptr)).Interface().(*int)) // @pointsto main.a
|
||||
// Non-pointer:
|
||||
print(reflect.Indirect(reflect.ValueOf([]*int{ptr})).Interface().([]*int)[0]) // @pointsto main.a
|
||||
}
|
||||
|
||||
func reflectNewAt() {
|
||||
var x [8]byte
|
||||
print(reflect.NewAt(reflect.TypeOf(3), unsafe.Pointer(&x)).Interface()) // @types *int
|
||||
}
|
||||
|
||||
// @warning "unsound: main.reflectNewAt contains a reflect.NewAt.. call"
|
||||
|
||||
func reflectTypeOf() {
|
||||
t := reflect.TypeOf(3)
|
||||
if unknown {
|
||||
t = reflect.TypeOf("foo")
|
||||
}
|
||||
// TODO(adonovan): make types.Eval let us refer to unexported types.
|
||||
print(t) // #@types *reflect.rtype
|
||||
print(reflect.Zero(t).Interface()) // @types int | string
|
||||
newint := reflect.New(t).Interface() // @line rtonew
|
||||
print(newint) // @types *int | *string
|
||||
print(newint.(*int)) // @pointsto <alloc in reflect.New>
|
||||
print(newint.(*string)) // @pointsto <alloc in reflect.New>
|
||||
}
|
||||
|
||||
func reflectTypeElem() {
|
||||
print(reflect.Zero(reflect.TypeOf(&a).Elem()).Interface()) // @types int
|
||||
print(reflect.Zero(reflect.TypeOf([]string{}).Elem()).Interface()) // @types string
|
||||
print(reflect.Zero(reflect.TypeOf(make(chan bool)).Elem()).Interface()) // @types bool
|
||||
print(reflect.Zero(reflect.TypeOf(make(map[string]float64)).Elem()).Interface()) // @types float64
|
||||
print(reflect.Zero(reflect.TypeOf([3]complex64{}).Elem()).Interface()) // @types complex64
|
||||
print(reflect.Zero(reflect.TypeOf(3).Elem()).Interface()) // @types
|
||||
print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem())) // @types interface{}
|
||||
print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()).Interface()) // @types
|
||||
}
|
||||
|
||||
// reflect.Values within reflect.Values.
|
||||
func metareflection() {
|
||||
// "box" a *int twice, unbox it twice.
|
||||
v0 := reflect.ValueOf(&a)
|
||||
print(v0) // @types *int
|
||||
v1 := reflect.ValueOf(v0) // box
|
||||
print(v1) // @types reflect.Value
|
||||
v2 := reflect.ValueOf(v1) // box
|
||||
print(v2) // @types reflect.Value
|
||||
v1a := v2.Interface().(reflect.Value) // unbox
|
||||
print(v1a) // @types reflect.Value
|
||||
v0a := v1a.Interface().(reflect.Value) // unbox
|
||||
print(v0a) // @types *int
|
||||
print(v0a.Interface().(*int)) // @pointsto main.a
|
||||
|
||||
// "box" an interface{} lvalue twice, unbox it twice.
|
||||
var iface interface{} = 3
|
||||
x0 := reflect.ValueOf(&iface).Elem()
|
||||
print(x0) // @types interface{}
|
||||
x1 := reflect.ValueOf(x0) // box
|
||||
print(x1) // @types reflect.Value
|
||||
x2 := reflect.ValueOf(x1) // box
|
||||
print(x2) // @types reflect.Value
|
||||
x1a := x2.Interface().(reflect.Value) // unbox
|
||||
print(x1a) // @types reflect.Value
|
||||
x0a := x1a.Interface().(reflect.Value) // unbox
|
||||
print(x0a) // @types interface{}
|
||||
print(x0a.Interface()) // @types int
|
||||
}
|
||||
|
||||
type T struct{}
|
||||
|
||||
// When the output of a type constructor flows to its input, we must
|
||||
// bound the set of types created to ensure termination of the algorithm.
|
||||
func typeCycle() {
|
||||
t := reflect.TypeOf(0)
|
||||
u := reflect.TypeOf("")
|
||||
v := reflect.TypeOf(T{})
|
||||
for unknown {
|
||||
t = reflect.PtrTo(t)
|
||||
t = reflect.SliceOf(t)
|
||||
|
||||
u = reflect.SliceOf(u)
|
||||
|
||||
if unknown {
|
||||
v = reflect.ChanOf(reflect.BothDir, v)
|
||||
} else {
|
||||
v = reflect.PtrTo(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Type height is bounded to about 4 map/slice/chan/pointer constructors.
|
||||
print(reflect.Zero(t).Interface()) // @types int | []*int | []*[]*int
|
||||
print(reflect.Zero(u).Interface()) // @types string | []string | [][]string | [][][]string | [][][][]string
|
||||
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
|
||||
}
|
||||
|
||||
func main() {
|
||||
reflectIndirect()
|
||||
reflectNewAt()
|
||||
reflectTypeOf()
|
||||
reflectTypeElem()
|
||||
metareflection()
|
||||
typeCycle()
|
||||
}
|
29
vendor/golang.org/x/tools/go/pointer/testdata/rtti.go
generated
vendored
Normal file
29
vendor/golang.org/x/tools/go/pointer/testdata/rtti.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
// Regression test for guru crash
|
||||
// https://code.google.com/p/go/issues/detail?id=6605
|
||||
//
|
||||
// Using reflection, methods may be called on types that are not the
|
||||
// operand of any ssa.MakeInterface instruction. In this example,
|
||||
// (Y).F is called by deriving the type Y from *Y. Prior to the fix,
|
||||
// no RTTI (or method set) for type Y was included in the program, so
|
||||
// the F() call would crash.
|
||||
|
||||
import "reflect"
|
||||
|
||||
var a int
|
||||
|
||||
type X struct{}
|
||||
|
||||
func (X) F() *int {
|
||||
return &a
|
||||
}
|
||||
|
||||
type I interface {
|
||||
F() *int
|
||||
}
|
||||
|
||||
func main() {
|
||||
type Y struct{ X }
|
||||
print(reflect.Indirect(reflect.ValueOf(new(Y))).Interface().(I).F()) // @pointsto main.a
|
||||
}
|
45
vendor/golang.org/x/tools/go/pointer/testdata/structreflect.go
generated
vendored
Normal file
45
vendor/golang.org/x/tools/go/pointer/testdata/structreflect.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
type A struct {
|
||||
f *int
|
||||
g interface{}
|
||||
h bool
|
||||
}
|
||||
|
||||
var dyn string
|
||||
|
||||
func reflectTypeFieldByName() {
|
||||
f, _ := reflect.TypeOf(A{}).FieldByName("f")
|
||||
print(f.Type) // @pointsto *int
|
||||
|
||||
g, _ := reflect.TypeOf(A{}).FieldByName("g")
|
||||
print(g.Type) // @pointsto interface{}
|
||||
print(reflect.Zero(g.Type)) // @pointsto <alloc in reflect.Zero>
|
||||
print(reflect.Zero(g.Type)) // @types interface{}
|
||||
|
||||
print(reflect.Zero(g.Type).Interface()) // @pointsto
|
||||
print(reflect.Zero(g.Type).Interface()) // @types
|
||||
|
||||
h, _ := reflect.TypeOf(A{}).FieldByName("h")
|
||||
print(h.Type) // @pointsto bool
|
||||
|
||||
missing, _ := reflect.TypeOf(A{}).FieldByName("missing")
|
||||
print(missing.Type) // @pointsto
|
||||
|
||||
dyn, _ := reflect.TypeOf(A{}).FieldByName(dyn)
|
||||
print(dyn.Type) // @pointsto *int | bool | interface{}
|
||||
}
|
||||
|
||||
func reflectTypeField() {
|
||||
fld := reflect.TypeOf(A{}).Field(0)
|
||||
print(fld.Type) // @pointsto *int | bool | interface{}
|
||||
}
|
||||
|
||||
func main() {
|
||||
reflectTypeFieldByName()
|
||||
reflectTypeField()
|
||||
}
|
100
vendor/golang.org/x/tools/go/pointer/testdata/structs.go
generated
vendored
Normal file
100
vendor/golang.org/x/tools/go/pointer/testdata/structs.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var unknown bool // defeat dead-code elimination
|
||||
|
||||
var p, q int
|
||||
|
||||
type A struct {
|
||||
f *int
|
||||
g interface{}
|
||||
}
|
||||
|
||||
func (a A) m1() {
|
||||
print(a.f) // @pointsto main.p
|
||||
}
|
||||
|
||||
func (a *A) m2() {
|
||||
print(a) // @pointsto complit.A@struct1s:9
|
||||
print(a.f) // @pointsto main.p
|
||||
}
|
||||
|
||||
type B struct {
|
||||
h *int
|
||||
A
|
||||
}
|
||||
|
||||
func structs1() {
|
||||
b := &B{ // @line struct1s
|
||||
h: &q,
|
||||
}
|
||||
b.f = &p
|
||||
b.g = b
|
||||
|
||||
print(b.h) // @pointsto main.q
|
||||
print(b.f) // @pointsto main.p
|
||||
print(b.g) // @types *B
|
||||
|
||||
ptr := &b.f
|
||||
print(*ptr) // @pointsto main.p
|
||||
|
||||
b.m1()
|
||||
b.m2()
|
||||
}
|
||||
|
||||
// @calls main.structs1 -> (main.A).m1
|
||||
// @calls main.structs1 -> (*main.A).m2
|
||||
// @calls (*main.B).m1 -> (main.A).m1
|
||||
// @calls (*main.B).m2 -> (*main.A).m2
|
||||
|
||||
type T struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
type S struct {
|
||||
a [3]T
|
||||
b *[3]T
|
||||
c [3]*T
|
||||
}
|
||||
|
||||
func structs2() {
|
||||
var s S // @line s2s
|
||||
print(&s) // @pointsto s@s2s:6
|
||||
print(&s.a) // @pointsto s.a@s2s:6
|
||||
print(&s.a[0]) // @pointsto s.a[*]@s2s:6
|
||||
print(&s.a[0].x) // @pointsto s.a[*].x@s2s:6
|
||||
print(&s.a[0].y) // @pointsto s.a[*].y@s2s:6
|
||||
print(&s.b) // @pointsto s.b@s2s:6
|
||||
print(&s.b[0]) // @pointsto
|
||||
print(&s.b[0].x) // @pointsto
|
||||
print(&s.b[0].y) // @pointsto
|
||||
print(&s.c) // @pointsto s.c@s2s:6
|
||||
print(&s.c[0]) // @pointsto s.c[*]@s2s:6
|
||||
print(&s.c[0].x) // @pointsto
|
||||
print(&s.c[0].y) // @pointsto
|
||||
|
||||
var s2 S // @line s2s2
|
||||
s2.b = new([3]T) // @line s2s2b
|
||||
print(s2.b) // @pointsto new@s2s2b:12
|
||||
print(&s2.b) // @pointsto s2.b@s2s2:6
|
||||
print(&s2.b[0]) // @pointsto new[*]@s2s2b:12
|
||||
print(&s2.b[0].x) // @pointsto new[*].x@s2s2b:12
|
||||
print(&s2.b[0].y) // @pointsto new[*].y@s2s2b:12
|
||||
print(&s2.c[0].x) // @pointsto
|
||||
print(&s2.c[0].y) // @pointsto
|
||||
|
||||
var s3 S // @line s2s3
|
||||
s3.c[2] = new(T) // @line s2s3c
|
||||
print(&s3.c) // @pointsto s3.c@s2s3:6
|
||||
print(s3.c[1]) // @pointsto new@s2s3c:15
|
||||
print(&s3.c[1]) // @pointsto s3.c[*]@s2s3:6
|
||||
print(&s3.c[1].x) // @pointsto new.x@s2s3c:15
|
||||
print(&s3.c[1].y) // @pointsto new.y@s2s3c:15
|
||||
}
|
||||
|
||||
func main() {
|
||||
structs1()
|
||||
structs2()
|
||||
}
|
24
vendor/golang.org/x/tools/go/pointer/testdata/timer.go
generated
vendored
Normal file
24
vendor/golang.org/x/tools/go/pointer/testdata/timer.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
func after() {}
|
||||
|
||||
func main() {
|
||||
// @calls time.startTimer -> time.sendTime
|
||||
ticker := time.NewTicker(1)
|
||||
<-ticker.C
|
||||
|
||||
// @calls time.startTimer -> time.sendTime
|
||||
timer := time.NewTimer(time.Second)
|
||||
<-timer.C
|
||||
|
||||
// @calls time.startTimer -> time.goFunc
|
||||
// @calls time.goFunc -> main.after
|
||||
timer = time.AfterFunc(time.Second, after)
|
||||
<-timer.C
|
||||
}
|
||||
|
||||
// @calls time.sendTime -> time.Now
|
Reference in New Issue
Block a user