GoPLS Viewer

Home|gopls/cmd/guru/testdata/src/calls/main.go
1package main
2
3import (
4    "fmt"
5)
6
7// Tests of call-graph queries.
8// See go.tools/guru/guru_test.go for explanation.
9// See calls.golden for expected query results.
10
11func A(x *int) { // @pointsto pointsto-A-x "x"
12    // @callers callers-A "^"
13    // @callstack callstack-A "^"
14}
15
16func B(x *int) { // @pointsto pointsto-B-x "x"
17    // @callers callers-B "^"
18}
19
20func foo() {
21}
22
23// apply is not (yet) treated context-sensitively.
24func apply(f func(x *int), x *int) {
25    f(x// @callees callees-apply "f"
26    // @callers callers-apply "^"
27}
28
29// store *is* treated context-sensitively,
30// so the points-to sets for pc, pd are precise.
31func store(ptr **intvalue *int) {
32    *ptr = value
33    // @callers callers-store "^"
34}
35
36func call(f func() *int) {
37    // Result points to anon function.
38    f() // @pointsto pointsto-result-f "f"
39
40    // Target of call is anon function.
41    f() // @callees callees-main.call-f "f"
42
43    // @callers callers-main.call "^"
44}
45
46func main() {
47    var ab int
48    go apply(A, &a// @callees callees-main-apply1 "app"
49    defer apply(B, &b)
50
51    var cd int
52    var pcpd *int // @pointsto pointsto-pc "pc"
53    store(&pc, &c)
54    store(&pd, &d)
55    _ = pd // @pointsto pointsto-pd "pd"
56
57    call(func() *int {
58        // We are called twice from main.call
59        // @callers callers-main.anon "^"
60        return &a
61    })
62
63    // Errors
64    _ = "no function call here"   // @callees callees-err-no-call "no"
65    print("builtin")              // @callees callees-err-builtin "builtin"
66    _ = string("type conversion"// @callees callees-err-conversion "str"
67    call(nil)                     // @callees callees-err-bad-selection "call\\(nil"
68    if false {
69        main() // @callees callees-err-deadcode1 "main"
70    }
71    var nilFunc func()
72    nilFunc() // @callees callees-err-nil-func "nilFunc"
73    var i interface {
74        f()
75    }
76    i.f() // @callees callees-err-nil-interface "i.f"
77
78    i = new(myint)
79    i.f() // @callees callees-not-a-wrapper "f"
80
81    // statically dispatched calls. Handled specially by callees, so test that they work.
82    foo()         // @callees callees-static-call "foo"
83    fmt.Println() // @callees callees-qualified-call "Println"
84    m := new(method)
85    m.f() // @callees callees-static-method-call "f"
86    g := new(embeddedIface)
87    g.iface = m
88    g.f() // @callees callees-implicit-selection-method-call "f"
89}
90
91type myint int
92
93func (myintf() {
94    // @callers callers-not-a-wrapper "^"
95}
96
97type method int
98
99func (methodf() {
100}
101
102type embeddedIface struct {
103    iface
104}
105
106type iface interface {
107    f()
108}
109
110var dynamic = func() {}
111
112func deadcode() {
113    main() // @callees callees-err-deadcode2 "main"
114    // @callers callers-err-deadcode "^"
115    // @callstack callstack-err-deadcode "^"
116
117    // Within dead code, dynamic calls have no callees.
118    dynamic() // @callees callees-err-deadcode3 "dynamic"
119}
120
121// This code belongs to init.
122var global = 123 // @callers callers-global "global"
123
124// The package initializer may be called by other packages' inits, or
125// in this case, the root of the callgraph.  The source-level init functions
126// are in turn called by it.
127func init() {
128    // @callstack callstack-init "^"
129}
130
MembersX
main.pc
init
method
A
store.value
main.pd
A.x
apply.f
B
main.b
main.d
myint.f
method.f
store
call
myint
iface
global
fmt
call.f
main.m
main.c
B.x
main
main.a
store.ptr
main.g
embeddedIface
deadcode
foo
apply
apply.x
Members
X