github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/test/escape_field.go (about)

     1  // errorcheck -0 -m -l
     2  
     3  // Copyright 2015 The Go Authors.  All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Test escape analysis with respect to field assignments.
     8  
     9  package escape
    10  
    11  var sink interface{}
    12  
    13  type X struct {
    14  	p1 *int
    15  	p2 *int
    16  	a  [2]*int
    17  }
    18  
    19  type Y struct {
    20  	x X
    21  }
    22  
    23  func field0() {
    24  	i := 0 // ERROR "moved to heap: i$"
    25  	var x X
    26  	x.p1 = &i // ERROR "&i escapes to heap$"
    27  	sink = x.p1 // ERROR "x\.p1 escapes to heap"
    28  }
    29  
    30  func field1() {
    31  	i := 0 // ERROR "moved to heap: i$"
    32  	var x X
    33  	// BAD: &i should not escape
    34  	x.p1 = &i // ERROR "&i escapes to heap$"
    35  	sink = x.p2 // ERROR "x\.p2 escapes to heap"
    36  }
    37  
    38  func field3() {
    39  	i := 0 // ERROR "moved to heap: i$"
    40  	var x X
    41  	x.p1 = &i // ERROR "&i escapes to heap$"
    42  	sink = x // ERROR "x escapes to heap"
    43  }
    44  
    45  func field4() {
    46  	i := 0 // ERROR "moved to heap: i$"
    47  	var y Y
    48  	y.x.p1 = &i // ERROR "&i escapes to heap$"
    49  	x := y.x
    50  	sink = x // ERROR "x escapes to heap"
    51  }
    52  
    53  func field5() {
    54  	i := 0 // ERROR "moved to heap: i$"
    55  	var x X
    56  	// BAD: &i should not escape here
    57  	x.a[0] = &i // ERROR "&i escapes to heap$"
    58  	sink = x.a[1] // ERROR "x\.a\[1\] escapes to heap"
    59  }
    60  
    61  // BAD: we are not leaking param x, only x.p2
    62  func field6(x *X) { // ERROR "leaking param: x$"
    63  	sink = x.p2 // ERROR "x\.p2 escapes to heap"
    64  }
    65  
    66  func field6a() {
    67  	i := 0  // ERROR "moved to heap: i$"
    68  	var x X // ERROR "moved to heap: x$"
    69  	// BAD: &i should not escape
    70  	x.p1 = &i // ERROR "&i escapes to heap$"
    71  	// BAD: &x should not escape
    72  	field6(&x) // ERROR "&x escapes to heap$"
    73  }
    74  
    75  func field7() {
    76  	i := 0
    77  	var y Y
    78  	y.x.p1 = &i // ERROR "field7 &i does not escape$"
    79  	x := y.x
    80  	var y1 Y
    81  	y1.x = x
    82  	_ = y1.x.p1
    83  }
    84  
    85  func field8() {
    86  	i := 0 // ERROR "moved to heap: i$"
    87  	var y Y
    88  	y.x.p1 = &i // ERROR "&i escapes to heap$"
    89  	x := y.x
    90  	var y1 Y
    91  	y1.x = x
    92  	sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap"
    93  }
    94  
    95  func field9() {
    96  	i := 0 // ERROR "moved to heap: i$"
    97  	var y Y
    98  	y.x.p1 = &i // ERROR "&i escapes to heap$"
    99  	x := y.x
   100  	var y1 Y
   101  	y1.x = x
   102  	sink = y1.x // ERROR "y1\.x escapes to heap"
   103  }
   104  
   105  func field10() {
   106  	i := 0 // ERROR "moved to heap: i$"
   107  	var y Y
   108  	// BAD: &i should not escape
   109  	y.x.p1 = &i // ERROR "&i escapes to heap$"
   110  	x := y.x
   111  	var y1 Y
   112  	y1.x = x
   113  	sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap"
   114  }
   115  
   116  func field11() {
   117  	i := 0         // ERROR "moved to heap: i$"
   118  	x := X{p1: &i} // ERROR "&i escapes to heap$"
   119  	sink = x.p1 // ERROR "x\.p1 escapes to heap"
   120  }
   121  
   122  func field12() {
   123  	i := 0 // ERROR "moved to heap: i$"
   124  	// BAD: &i should not escape
   125  	x := X{p1: &i} // ERROR "&i escapes to heap$"
   126  	sink = x.p2 // ERROR "x\.p2 escapes to heap"
   127  }
   128  
   129  func field13() {
   130  	i := 0          // ERROR "moved to heap: i$"
   131  	x := &X{p1: &i} // ERROR "&i escapes to heap$" "field13 &X literal does not escape$"
   132  	sink = x.p1 // ERROR "x\.p1 escapes to heap"
   133  }
   134  
   135  func field14() {
   136  	i := 0 // ERROR "moved to heap: i$"
   137  	// BAD: &i should not escape
   138  	x := &X{p1: &i} // ERROR "&i escapes to heap$" "field14 &X literal does not escape$"
   139  	sink = x.p2 // ERROR "x\.p2 escapes to heap"
   140  }
   141  
   142  func field15() {
   143  	i := 0          // ERROR "moved to heap: i$"
   144  	x := &X{p1: &i} // ERROR "&X literal escapes to heap$" "&i escapes to heap$"
   145  	sink = x // ERROR "x escapes to heap"
   146  }
   147  
   148  func field16() {
   149  	i := 0 // ERROR "moved to heap: i$"
   150  	var x X
   151  	// BAD: &i should not escape
   152  	x.p1 = &i // ERROR "&i escapes to heap$"
   153  	var iface interface{} = x // ERROR "x escapes to heap"
   154  	x1 := iface.(X)
   155  	sink = x1.p2 // ERROR "x1\.p2 escapes to heap"
   156  }
   157  
   158  func field17() {
   159  	i := 0 // ERROR "moved to heap: i$"
   160  	var x X
   161  	x.p1 = &i // ERROR "&i escapes to heap$"
   162  	var iface interface{} = x // ERROR "x escapes to heap"
   163  	x1 := iface.(X)
   164  	sink = x1.p1 // ERROR "x1\.p1 escapes to heap"
   165  }
   166  
   167  func field18() {
   168  	i := 0 // ERROR "moved to heap: i$"
   169  	var x X
   170  	// BAD: &i should not escape
   171  	x.p1 = &i // ERROR "&i escapes to heap$"
   172  	var iface interface{} = x // ERROR "x escapes to heap"
   173  	y, _ := iface.(Y) // Put X, but extracted Y. The cast will fail, so y is zero initialized.
   174  	sink = y // ERROR "y escapes to heap"
   175  }