modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/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 content: 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
    69  	// BAD: &i should not escape
    70  	x.p1 = &i  // ERROR "&i escapes to heap$"
    71  	field6(&x) // ERROR "field6a &x does not escape"
    72  }
    73  
    74  func field7() {
    75  	i := 0
    76  	var y Y
    77  	y.x.p1 = &i // ERROR "field7 &i does not escape$"
    78  	x := y.x
    79  	var y1 Y
    80  	y1.x = x
    81  	_ = y1.x.p1
    82  }
    83  
    84  func field8() {
    85  	i := 0 // ERROR "moved to heap: i$"
    86  	var y Y
    87  	y.x.p1 = &i // ERROR "&i escapes to heap$"
    88  	x := y.x
    89  	var y1 Y
    90  	y1.x = x
    91  	sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap"
    92  }
    93  
    94  func field9() {
    95  	i := 0 // ERROR "moved to heap: i$"
    96  	var y Y
    97  	y.x.p1 = &i // ERROR "&i escapes to heap$"
    98  	x := y.x
    99  	var y1 Y
   100  	y1.x = x
   101  	sink = y1.x // ERROR "y1\.x escapes to heap"
   102  }
   103  
   104  func field10() {
   105  	i := 0 // ERROR "moved to heap: i$"
   106  	var y Y
   107  	// BAD: &i should not escape
   108  	y.x.p1 = &i // ERROR "&i escapes to heap$"
   109  	x := y.x
   110  	var y1 Y
   111  	y1.x = x
   112  	sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap"
   113  }
   114  
   115  func field11() {
   116  	i := 0         // ERROR "moved to heap: i$"
   117  	x := X{p1: &i} // ERROR "&i escapes to heap$"
   118  	sink = x.p1    // ERROR "x\.p1 escapes to heap"
   119  }
   120  
   121  func field12() {
   122  	i := 0 // ERROR "moved to heap: i$"
   123  	// BAD: &i should not escape
   124  	x := X{p1: &i} // ERROR "&i escapes to heap$"
   125  	sink = x.p2    // ERROR "x\.p2 escapes to heap"
   126  }
   127  
   128  func field13() {
   129  	i := 0          // ERROR "moved to heap: i$"
   130  	x := &X{p1: &i} // ERROR "&i escapes to heap$" "field13 &X literal does not escape$"
   131  	sink = x.p1     // ERROR "x\.p1 escapes to heap"
   132  }
   133  
   134  func field14() {
   135  	i := 0 // ERROR "moved to heap: i$"
   136  	// BAD: &i should not escape
   137  	x := &X{p1: &i} // ERROR "&i escapes to heap$" "field14 &X literal does not escape$"
   138  	sink = x.p2     // ERROR "x\.p2 escapes to heap"
   139  }
   140  
   141  func field15() {
   142  	i := 0          // ERROR "moved to heap: i$"
   143  	x := &X{p1: &i} // ERROR "&X literal escapes to heap$" "&i escapes to heap$"
   144  	sink = x        // ERROR "x escapes to heap"
   145  }
   146  
   147  func field16() {
   148  	i := 0 // ERROR "moved to heap: i$"
   149  	var x X
   150  	// BAD: &i should not escape
   151  	x.p1 = &i                 // ERROR "&i escapes to heap$"
   152  	var iface interface{} = x // ERROR "x escapes to heap"
   153  	x1 := iface.(X)
   154  	sink = x1.p2 // ERROR "x1\.p2 escapes to heap"
   155  }
   156  
   157  func field17() {
   158  	i := 0 // ERROR "moved to heap: i$"
   159  	var x X
   160  	x.p1 = &i                 // ERROR "&i escapes to heap$"
   161  	var iface interface{} = x // ERROR "x escapes to heap"
   162  	x1 := iface.(X)
   163  	sink = x1.p1 // ERROR "x1\.p1 escapes to heap"
   164  }
   165  
   166  func field18() {
   167  	i := 0 // ERROR "moved to heap: i$"
   168  	var x X
   169  	// BAD: &i should not escape
   170  	x.p1 = &i                 // ERROR "&i escapes to heap$"
   171  	var iface interface{} = x // ERROR "x escapes to heap"
   172  	y, _ := iface.(Y)         // Put X, but extracted Y. The cast will fail, so y is zero initialized.
   173  	sink = y                  // ERROR "y escapes to heap"
   174  }