github.com/golangci/go-tools@v0.0.0-20190318060251-af6baa5dc196/ssa/testdata/objlookup.go (about) 1 //+build ignore 2 3 package 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 18 import "fmt" 19 import "os" 20 21 type J int 22 23 func (*J) method() {} 24 25 const globalConst = 0 26 27 var globalVar int // &globalVar::Global 28 29 func globalFunc() {} 30 31 type I interface { 32 interfaceMethod() 33 } 34 35 type S struct { 36 x int // x::nil 37 } 38 39 func main() { 40 print(globalVar) // globalVar::UnOp 41 globalVar = 1 // globalVar::Const 42 43 var v0 int = 1 // v0::Const (simple local value spec) 44 if v0 > 0 { // v0::Const 45 v0 = 2 // v0::Const 46 } 47 print(v0) // v0::Phi 48 49 // v1 is captured and thus implicitly address-taken. 50 var v1 int = 1 // v1::Const 51 v1 = 2 // v1::Const 52 fmt.Println(v1) // v1::UnOp (load) 53 f := func(param int) { // f::MakeClosure param::Parameter 54 if y := 1; y > 0 { // y::Const 55 print(v1, param) // v1::UnOp (load) param::Parameter 56 } 57 param = 2 // param::Const 58 println(param) // param::Const 59 } 60 61 f(0) // f::MakeClosure 62 63 var v2 int // v2::Const (implicitly zero-initialized local value spec) 64 print(v2) // v2::Const 65 66 m := make(map[string]int) // m::MakeMap 67 68 // Local value spec with multi-valued RHS: 69 var v3, v4 = m[""] // v3::Extract v4::Extract m::MakeMap 70 print(v3) // v3::Extract 71 print(v4) // v4::Extract 72 73 v3++ // v3::BinOp (assign with op) 74 v3 += 2 // v3::BinOp (assign with op) 75 76 v5, v6 := false, "" // v5::Const v6::Const (defining assignment) 77 print(v5) // v5::Const 78 print(v6) // v6::Const 79 80 var v7 S // &v7::Alloc 81 v7.x = 1 // &v7::Alloc &x::FieldAddr 82 print(v7.x) // &v7::Alloc &x::FieldAddr 83 84 var v8 [1]int // &v8::Alloc 85 v8[0] = 0 // &v8::Alloc 86 print(v8[:]) // &v8::Alloc 87 _ = v8[0] // &v8::Alloc 88 _ = v8[:][0] // &v8::Alloc 89 v8ptr := &v8 // v8ptr::Alloc &v8::Alloc 90 _ = v8ptr[0] // v8ptr::Alloc 91 _ = *v8ptr // v8ptr::Alloc 92 93 v8a := make([]int, 1) // v8a::Slice 94 v8a[0] = 0 // v8a::Slice 95 print(v8a[:]) // v8a::Slice 96 97 v9 := S{} // &v9::Alloc 98 99 v10 := &v9 // v10::Alloc &v9::Alloc 100 _ = v10 // v10::Alloc 101 102 var v11 *J = nil // v11::Const 103 v11.method() // v11::Const 104 105 var v12 J // &v12::Alloc 106 v12.method() // &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 // v11::Const 113 _ = (*struct{ J }).method // J::nil 114 115 // These vars are not optimised away. 116 if false { 117 v13 := 0 // v13::Const 118 println(v13) // v13::Const 119 } 120 121 switch x := 1; x { // x::Const 122 case v0: // v0::Phi 123 } 124 125 for k, v := range m { // k::Extract v::Extract m::MakeMap 126 _ = k // k::Extract 127 v++ // v::BinOp 128 } 129 130 if y := 0; y > 1 { // y::Const y::Const 131 } 132 133 var i interface{} // i::Const (nil interface) 134 i = 1 // i::MakeInterface 135 switch i := i.(type) { // i::MakeInterface i::MakeInterface 136 case int: 137 println(i) // i::Extract 138 } 139 140 ch := make(chan int) // ch::MakeChan 141 select { 142 case x := <-ch: // x::UnOp (receive) ch::MakeChan 143 _ = x // x::UnOp 144 } 145 146 // .Op is an inter-package FieldVal-selection. 147 var err os.PathError // &err::Alloc 148 _ = err.Op // &err::Alloc &Op::FieldAddr 149 _ = &err.Op // &err::Alloc &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 // n::Const 155 n1 := n // n1::Const n::Const 156 n2 := &n1 // n2::Alloc &n1::Alloc 157 n3 := *n2 // n3::UnOp n2::Alloc 158 n4 := **n3 // n4::UnOp n3::UnOp 159 _ = n4 // n4::UnOp 160 }