Home | History | Annotate | Download | only in test
      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 }
    175