Add generated file

This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
xing-yang
2018-07-12 10:55:15 -07:00
parent 36b1de0341
commit e213d1890d
17729 changed files with 5090889 additions and 0 deletions

View 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

View 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
}

View 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()
}

View 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()
}

View 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()
}

View 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()
}

View 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()
}

View 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
View 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()
}

View 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
}

View 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
View 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()
}

View 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
View 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

View 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
View 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

View 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()
}

View 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)
}

View 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
View 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
View 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
View File

@@ -0,0 +1,11 @@
// +build ignore
package main
// Analysis abstraction of recursive calls is finite.
func main() {
main()
}
// @calls main.main -> main.main

View 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
View 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
}

View 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()
}

View 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
View 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