github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/callgraph/vta/testdata/src/callgraph_pointers.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // go:build ignore 6 7 package testdata 8 9 type I interface { 10 Foo() 11 } 12 13 type A struct { 14 f *I 15 } 16 17 func (a A) Foo() {} 18 19 type B struct{} 20 21 func (b B) Foo() {} 22 23 func Do(a A, i I, c bool) *I { 24 if c { 25 *a.f = a 26 } else { 27 a.f = &i 28 } 29 (*a.f).Foo() 30 return &i 31 } 32 33 func Baz(a A, b B, c bool) { 34 x := Do(a, b, c) 35 (*x).Foo() 36 } 37 38 // Relevant SSA: 39 // func Baz(a A, b B, c bool): 40 // t0 = local A (a) 41 // ... 42 // t5 = Do(t2, t4, c) 43 // t6 = *t5 44 // t7 = invoke t6.Foo() 45 // return 46 47 // func Do(a A, i I, c bool) *I: 48 // t0 = local A (a) 49 // *t0 = a 50 // ... 51 // if c goto 1 else 3 52 // 1: 53 // t2 = &t0.f [#0] 54 // ... 55 // jump 2 56 // 2: 57 // t6 = &t0.f [#0] 58 // ... 59 // t9 = invoke t8.Foo() 60 // return t1 61 // 3: 62 // t10 = &t0.f [#0] alias between A.f and t10 63 // *t10 = t1 alias between t10 and t1 64 // jump 2 65 66 // The command a.f = &i introduces aliasing that results in 67 // A and B reaching both *A.f and return value of Do(a, b, c). 68 69 // WANT: 70 // Baz: Do(t2, t4, c) -> Do; invoke t6.Foo() -> A.Foo, B.Foo 71 // Do: invoke t8.Foo() -> A.Foo, B.Foo