GoPLS Viewer

Home|gopls/go/ssa/testdata/objlookup.go
1// +build ignore
2
3package main
4
5// This file is the input to TestObjValueLookup in source_test.go,
6// which ensures that each occurrence of an ident defining or
7// referring to a func, var or const object can be mapped to its
8// corresponding SSA Value.
9//
10// For every reference to a var object, we use annotations in comments
11// to denote both the expected SSA Value kind, and whether to expect
12// its value (x) or its address (&x).
13//
14// For const and func objects, the results don't vary by reference and
15// are always values not addresses, so no annotations are needed.  The
16// declaration is enough.
17
18import "fmt"
19import "os"
20
21type J int
22
23func (*Jmethod() {}
24
25const globalConst = 0
26
27var globalVar int //@ ssa(globalVar,"&Global")
28
29func globalFunc() {}
30
31type I interface {
32    interfaceMethod()
33}
34
35type S struct {
36    x int //@ ssa(x,"nil")
37}
38
39func main() {
40    print(globalVar//@ ssa(globalVar,"UnOp")
41    globalVar = 1    //@ ssa(globalVar,"Const")
42
43    var v0 int = 1 //@ ssa(v0,"Const") // simple local value spec
44    if v0 > 0 {    //@ ssa(v0,"Const")
45        v0 = 2 //@ ssa(v0,"Const")
46    }
47    print(v0//@ ssa(v0,"Phi")
48
49    // v1 is captured and thus implicitly address-taken.
50    var v1 int = 1         //@ ssa(v1,"Const")
51    v1 = 2                 //@ ssa(v1,"Const")
52    fmt.Println(v1)        //@ ssa(v1,"UnOp") // load
53    f := func(param int) { //@ ssa(f,"MakeClosure"), ssa(param,"Parameter")
54        if y := 1y > 0 { //@ ssa(y,"Const")
55            print(v1param//@ ssa(v1,"UnOp") /*load*/, ssa(param,"Parameter")
56        }
57        param = 2      //@ ssa(param,"Const")
58        println(param//@ ssa(param,"Const")
59    }
60
61    f(0//@ ssa(f,"MakeClosure")
62
63    var v2 int //@ ssa(v2,"Const") // implicitly zero-initialized local value spec
64    print(v2)  //@ ssa(v2,"Const")
65
66    m := make(map[string]int//@ ssa(m,"MakeMap")
67
68    // Local value spec with multi-valued RHS:
69    var v3v4 = m[""//@ ssa(v3,"Extract"), ssa(v4,"Extract"), ssa(m,"MakeMap")
70    print(v3)          //@ ssa(v3,"Extract")
71    print(v4)          //@ ssa(v4,"Extract")
72
73    v3++    //@ ssa(v3,"BinOp") // assign with op
74    v3 += 2 //@ ssa(v3,"BinOp") // assign with op
75
76    v5v6 := false"" //@ ssa(v5,"Const"), ssa(v6,"Const") // defining assignment
77    print(v5)           //@ ssa(v5,"Const")
78    print(v6)           //@ ssa(v6,"Const")
79
80    var v7 S    //@ ssa(v7,"&Alloc")
81    v7.x = 1    //@ ssa(v7,"&Alloc"), ssa(x,"&FieldAddr")
82    print(v7.x//@ ssa(v7,"&Alloc"), ssa(x,"&FieldAddr")
83
84    var v8 [1]int //@ ssa(v8,"&Alloc")
85    v8[0] = 0     //@ ssa(v8,"&Alloc")
86    print(v8[:])  //@ ssa(v8,"&Alloc")
87    _ = v8[0]     //@ ssa(v8,"&Alloc")
88    _ = v8[:][0]  //@ ssa(v8,"&Alloc")
89    v8ptr := &v8  //@ ssa(v8ptr,"Alloc"), ssa(v8,"&Alloc")
90    _ = v8ptr[0]  //@ ssa(v8ptr,"Alloc")
91    _ = *v8ptr    //@ ssa(v8ptr,"Alloc")
92
93    v8a := make([]int1//@ ssa(v8a,"Slice")
94    v8a[0] = 0            //@ ssa(v8a,"Slice")
95    print(v8a[:])         //@ ssa(v8a,"Slice")
96
97    v9 := S{} //@ ssa(v9,"&Alloc")
98
99    v10 := &v9 //@ ssa(v10,"Alloc"), ssa(v9,"&Alloc")
100    _ = v10    //@ ssa(v10,"Alloc")
101
102    var v11 *J = nil //@ ssa(v11,"Const")
103    v11.method()     //@ ssa(v11,"Const")
104
105    var v12 J    //@ ssa(v12,"&Alloc")
106    v12.method() //@ ssa(v12,"&Alloc") // implicitly address-taken
107
108    // NB, in the following, 'method' resolves to the *types.Func
109    // of (*J).method, so it doesn't help us locate the specific
110    // ssa.Values here: a bound-method closure and a promotion
111    // wrapper.
112    _ = v11.method            //@ ssa(v11,"Const")
113    _ = (*struct{ J }).method //@ ssa(J,"nil")
114
115    // These vars are not optimised away.
116    if false {
117        v13 := 0     //@ ssa(v13,"Const")
118        println(v13//@ ssa(v13,"Const")
119    }
120
121    switch x := 1x { //@ ssa(x,"Const")
122    case v0//@ ssa(v0,"Phi")
123    }
124
125    for kv := range m { //@ ssa(k,"Extract"), ssa(v,"Extract"), ssa(m,"MakeMap")
126        _ = k //@ ssa(k,"Extract")
127        v++   //@ ssa(v,"BinOp")
128    }
129
130    if y := 0y > 1 { //@ ssa(y,"Const"), ssa(y,"Const")
131    }
132
133    var i interface{}      //@ ssa(i,"Const") // nil interface
134    i = 1                  //@ ssa(i,"MakeInterface")
135    switch i := i.(type) { //@ ssa(i,"MakeInterface"), ssa(i,"MakeInterface")
136    case int:
137        println(i//@ ssa(i,"Extract")
138    }
139
140    ch := make(chan int//@ ssa(ch,"MakeChan")
141    select {
142    case x := <-ch//@ ssa(x,"UnOp") /*receive*/, ssa(ch,"MakeChan")
143        _ = x //@ ssa(x,"UnOp")
144    }
145
146    // .Op is an inter-package FieldVal-selection.
147    var err os.PathError //@ ssa(err,"&Alloc")
148    _ = err.Op           //@ ssa(err,"&Alloc"), ssa(Op,"&FieldAddr")
149    _ = &err.Op          //@ ssa(err,"&Alloc"), ssa(Op,"&FieldAddr")
150
151    // Exercise corner-cases of lvalues vs rvalues.
152    // (Guessing IsAddr from the 'pointerness' won't cut it here.)
153    type N *N
154    var n N    //@ ssa(n,"Const")
155    n1 := n    //@ ssa(n1,"Const"), ssa(n,"Const")
156    n2 := &n1  //@ ssa(n2,"Alloc"), ssa(n1,"&Alloc")
157    n3 := *n2  //@ ssa(n3,"UnOp"), ssa(n2,"Alloc")
158    n4 := **n3 //@ ssa(n4,"UnOp"), ssa(n3,"UnOp")
159    _ = n4     //@ ssa(n4,"UnOp")
160}
161
MembersX
main.v1
main.BlockStmt.y
main.v9
main.ch
main.err
main.N
globalVar
globalFunc
main.v5
main.v10
main.x
S
main.m
main.RangeStmt_3617.k
main.n2
main.v8ptr
main.BlockStmt.v13
main.n3
S.x
main.v12
main.v7
main.v8
main.v8a
main.y
I
main.v6
globalConst
main
fmt
J.method
main.BlockStmt.x
main.n
main.n1
J
main.v2
main.v11
main.RangeStmt_3617.v
os
main.v0
Members
X