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  }