1 | //go:build ignore |
---|---|
2 | // +build ignore |
3 | |
4 | package main |
5 | |
6 | type I interface { |
7 | f() |
8 | } |
9 | |
10 | type C int |
11 | |
12 | func (*C) f() {} |
13 | |
14 | type D struct{ ptr *int } |
15 | |
16 | func (D) f() {} |
17 | |
18 | type E struct{} |
19 | |
20 | func (*E) f() {} |
21 | |
22 | var a, b int |
23 | |
24 | var unknown bool // defeat dead-code elimination |
25 | |
26 | func 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 | |
47 | func 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 | |
78 | func 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 | |
88 | func 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 | |
111 | type J interface { |
112 | f(*int) *int |
113 | } |
114 | |
115 | type P struct { |
116 | x int |
117 | } |
118 | |
119 | func (p *P) f(pi *int) *int { |
120 | print(p) // @pointsto p@i5p:6 |
121 | print(pi) // @pointsto i@i5i:6 |
122 | return &p.x |
123 | } |
124 | |
125 | func 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 | |
137 | func 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 | |
146 | func main() { |
147 | interface1() |
148 | interface2() |
149 | interface3() |
150 | interface4() |
151 | interface5() |
152 | interface6() |
153 | } |
154 |
Members