10 func f(p *int, q hasF) *int {
11 print(p) // @pointsto main.a
13 print(q.(*T)) // @pointsto new@newT1:22
17 func g(p *bool) (*int, *bool, hasF) {
18 return &b, p, new(T) // @line newT2
21 func reflectValueCall() {
22 rvf := reflect.ValueOf(f)
23 res := rvf.Call([]reflect.Value{
24 // argument order is not significant:
25 reflect.ValueOf(new(T)), // @line newT1
28 print(res[0].Interface()) // @types *int
29 print(res[0].Interface().(*int)) // @pointsto main.b
32 // @calls main.reflectValueCall -> main.f
34 func reflectValueCallIndirect() {
35 rvf := reflect.ValueOf(g)
36 call := rvf.Call // kids, don't try this at home
38 // Indirect call uses shared contour.
40 // Also notice that argument position doesn't matter, and args
41 // of inappropriate type (e.g. 'a') are ignored.
42 res := call([]reflect.Value{
44 reflect.ValueOf(&false2),
46 res0 := res[0].Interface()
47 print(res0) // @types *int | *bool | *T
48 print(res0.(*int)) // @pointsto main.b
49 print(res0.(*bool)) // @pointsto main.false2
50 print(res0.(hasF)) // @types *T
51 print(res0.(*T)) // @pointsto new@newT2:19
54 // @calls main.reflectValueCallIndirect -> (reflect.Value).Call$bound
55 // @calls (reflect.Value).Call$bound -> main.g
57 func reflectTypeInOut() {
58 var f func(float64, bool) (string, int)
59 print(reflect.Zero(reflect.TypeOf(f).In(0)).Interface()) // @types float64
60 print(reflect.Zero(reflect.TypeOf(f).In(1)).Interface()) // @types bool
61 print(reflect.Zero(reflect.TypeOf(f).In(-1)).Interface()) // @types float64 | bool
62 print(reflect.Zero(reflect.TypeOf(f).In(zero)).Interface()) // @types float64 | bool
64 print(reflect.Zero(reflect.TypeOf(f).Out(0)).Interface()) // @types string
65 print(reflect.Zero(reflect.TypeOf(f).Out(1)).Interface()) // @types int
66 print(reflect.Zero(reflect.TypeOf(f).Out(2)).Interface()) // @types
68 print(reflect.Zero(reflect.TypeOf(3).Out(0)).Interface()) // @types
91 func reflectTypeMethodByName() {
92 TU := reflect.TypeOf([]interface{}{T{}, U{}}[0])
93 print(reflect.Zero(TU)) // @types T | U
95 F, _ := TU.MethodByName("F")
96 print(reflect.Zero(F.Type)) // @types func(T) | func(U, int)
97 print(F.Func) // @pointsto (main.T).F | (main.U).F
99 g, _ := TU.MethodByName("g")
100 print(reflect.Zero(g.Type)) // @types func(T, int) | func(U, string)
101 print(g.Func) // @pointsto (main.T).g | (main.U).g
103 // Non-literal method names are treated less precisely.
104 U := reflect.TypeOf(U{})
105 X, _ := U.MethodByName(nonconst)
106 print(reflect.Zero(X.Type)) // @types func(U, int) | func(U, string)
107 print(X.Func) // @pointsto (main.U).F | (main.U).g
109 // Interface methods.
110 rThasF := reflect.TypeOf(new(hasF)).Elem()
111 print(reflect.Zero(rThasF)) // @types hasF
112 F2, _ := rThasF.MethodByName("F")
113 print(reflect.Zero(F2.Type)) // @types func()
114 print(F2.Func) // @pointsto
118 func reflectTypeMethod() {
119 m := reflect.TypeOf(T{}).Method(0)
120 print(reflect.Zero(m.Type)) // @types func(T) | func(T, int)
121 print(m.Func) // @pointsto (main.T).F | (main.T).g
126 reflectValueCallIndirect()
128 reflectTypeMethodByName()