GoPLS Viewer

Home|gopls/go/pointer/testdata/interfaces.go
1//go:build ignore
2// +build ignore
3
4package main
5
6type I interface {
7    f()
8}
9
10type C int
11
12func (*Cf() {}
13
14type D struct{ ptr *int }
15
16func (Df() {}
17
18type E struct{}
19
20func (*Ef() {}
21
22var ab int
23
24var unknown bool // defeat dead-code elimination
25
26func interface1() {
27    var i interface{} = &a
28    var j interface{} = D{&b}
29    k := j
30    if unknown {
31        k = i
32    }
33
34    print(i// @types *int
35    print(j// @types D
36    print(k// @types *int | D
37
38    print(i.(*int)) // @pointsto command-line-arguments.a
39    print(j.(*int)) // @pointsto
40    print(k.(*int)) // @pointsto command-line-arguments.a
41
42    print(i.(D).ptr// @pointsto
43    print(j.(D).ptr// @pointsto command-line-arguments.b
44    print(k.(D).ptr// @pointsto command-line-arguments.b
45}
46
47func interface2() {
48    var i I = (*C)(&a)
49    var j I = D{&a}
50    k := j
51    if unknown {
52        k = i
53    }
54
55    print(i// @types *C
56    print(j// @types D
57    print(k// @types *C | D
58    print(k// @pointsto makeinterface:command-line-arguments.D | makeinterface:*command-line-arguments.C
59
60    k.f()
61    // @calls command-line-arguments.interface2 -> (*command-line-arguments.C).f
62    // @calls command-line-arguments.interface2 -> (command-line-arguments.D).f
63
64    print(i.(*C))    // @pointsto command-line-arguments.a
65    print(j.(D).ptr// @pointsto command-line-arguments.a
66    print(k.(*C))    // @pointsto command-line-arguments.a
67
68    switch x := k.(type) {
69    case *C:
70        print(x// @pointsto command-line-arguments.a
71    case D:
72        print(x.ptr// @pointsto command-line-arguments.a
73    case *E:
74        print(x// @pointsto
75    }
76}
77
78func interface3() {
79    // There should be no backflow of concrete types from the type-switch to x.
80    var x interface{} = 0
81    print(x// @types int
82    switch x.(type) {
83    case int:
84    case string:
85    }
86}
87
88func interface4() {
89    var i interface{} = D{&a}
90    if unknown {
91        i = 123
92    }
93
94    print(i// @types int | D
95
96    j := i.(I)       // interface narrowing type-assertion
97    print(j)         // @types D
98    print(j.(D).ptr// @pointsto command-line-arguments.a
99
100    var l interface{} = j // interface widening assignment.
101    print(l)              // @types D
102    print(l.(D).ptr)      // @pointsto command-line-arguments.a
103
104    m := j.(interface{}) // interface widening type-assertion.
105    print(m)             // @types D
106    print(m.(D).ptr)     // @pointsto command-line-arguments.a
107}
108
109// Interface method calls and value flow:
110
111type J interface {
112    f(*int) *int
113}
114
115type P struct {
116    x int
117}
118
119func (p *Pf(pi *int) *int {
120    print(p)  // @pointsto p@i5p:6
121    print(pi// @pointsto i@i5i:6
122    return &p.x
123}
124
125func interface5() {
126    var p P // @line i5p
127    var j J = &p
128    var i int      // @line i5i
129    print(j.f(&i)) // @pointsto p.x@i5p:6
130    print(&i)      // @pointsto i@i5i:6
131
132    print(j// @pointsto makeinterface:*command-line-arguments.P
133}
134
135// @calls command-line-arguments.interface5 -> (*command-line-arguments.P).f
136
137func interface6() {
138    f := I.f
139    print(f// @pointsto (command-line-arguments.I).f$thunk
140    f(new(struct{ D }))
141}
142
143// @calls command-line-arguments.interface6 -> (command-line-arguments.I).f$thunk
144// @calls (command-line-arguments.I).f$thunk -> (*struct{command-line-arguments.D}).f
145
146func main() {
147    interface1()
148    interface2()
149    interface3()
150    interface4()
151    interface5()
152    interface6()
153}
154
MembersX
P
P.x
interface5
interface6.f
D.ptr
interface2
J
P.f.p
P.f
interface5.p
interface2.j
interface3
interface2.k
interface4
interface5.j
C.f
interface1.k
interface2.i
P.f.pi
interface5.i
interface6
C
interface1
Members
X