+++ /dev/null
-// +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()
-}