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 for interface conversions.
      8 
      9 package escape
     10 
     11 var sink interface{}
     12 
     13 type M interface {
     14 	M()
     15 }
     16 
     17 func mescapes(m M) { // ERROR "leaking param: m"
     18 	sink = m // ERROR "m escapes to heap"
     19 }
     20 
     21 func mdoesnotescape(m M) { // ERROR "m does not escape"
     22 }
     23 
     24 // Tests for type stored directly in iface and with value receiver method.
     25 type M0 struct {
     26 	p *int
     27 }
     28 
     29 func (M0) M() {
     30 }
     31 
     32 func efaceEscape0() {
     33 	{
     34 		i := 0
     35 		v := M0{&i} // ERROR "&i does not escape"
     36 		var x M = v // ERROR "v does not escape"
     37 		_ = x
     38 	}
     39 	{
     40 		i := 0      // ERROR "moved to heap: i"
     41 		v := M0{&i} // ERROR "&i escapes to heap"
     42 		var x M = v // ERROR "v escapes to heap"
     43 		sink = x    // ERROR "x escapes to heap"
     44 	}
     45 	{
     46 		i := 0
     47 		v := M0{&i} // ERROR "&i does not escape"
     48 		var x M = v // ERROR "v does not escape"
     49 		v1 := x.(M0)
     50 		_ = v1
     51 	}
     52 	{
     53 		i := 0      // ERROR "moved to heap: i"
     54 		v := M0{&i} // ERROR "&i escapes to heap"
     55 		// BAD: v does not escape to heap here
     56 		var x M = v // ERROR "v escapes to heap"
     57 		v1 := x.(M0)
     58 		sink = v1 // ERROR "v1 escapes to heap"
     59 	}
     60 	{
     61 		i := 0      // ERROR "moved to heap: i"
     62 		v := M0{&i} // ERROR "&i escapes to heap"
     63 		// BAD: v does not escape to heap here
     64 		var x M = v // ERROR "v escapes to heap"
     65 		x.M()
     66 	}
     67 	{
     68 		i := 0      // ERROR "moved to heap: i"
     69 		v := M0{&i} // ERROR "&i escapes to heap"
     70 		var x M = v // ERROR "v escapes to heap"
     71 		mescapes(x)
     72 	}
     73 	{
     74 		i := 0
     75 		v := M0{&i} // ERROR "&i does not escape"
     76 		var x M = v // ERROR "v does not escape"
     77 		mdoesnotescape(x)
     78 	}
     79 }
     80 
     81 // Tests for type stored indirectly in iface and with value receiver method.
     82 type M1 struct {
     83 	p *int
     84 	x int
     85 }
     86 
     87 func (M1) M() {
     88 }
     89 
     90 func efaceEscape1() {
     91 	{
     92 		i := 0
     93 		v := M1{&i, 0} // ERROR "&i does not escape"
     94 		var x M = v    // ERROR "v does not escape"
     95 		_ = x
     96 	}
     97 	{
     98 		i := 0         // ERROR "moved to heap: i"
     99 		v := M1{&i, 0} // ERROR "&i escapes to heap"
    100 		var x M = v    // ERROR "v escapes to heap"
    101 		sink = x       // ERROR "x escapes to heap"
    102 	}
    103 	{
    104 		i := 0
    105 		v := M1{&i, 0} // ERROR "&i does not escape"
    106 		var x M = v    // ERROR "v does not escape"
    107 		v1 := x.(M1)
    108 		_ = v1
    109 	}
    110 	{
    111 		i := 0         // ERROR "moved to heap: i"
    112 		v := M1{&i, 0} // ERROR "&i escapes to heap"
    113 		// BAD: v does not escape to heap here
    114 		var x M = v // ERROR "v escapes to heap"
    115 		v1 := x.(M1)
    116 		sink = v1 // ERROR "v1 escapes to heap"
    117 	}
    118 	{
    119 		i := 0         // ERROR "moved to heap: i"
    120 		v := M1{&i, 0} // ERROR "&i escapes to heap"
    121 		// BAD: v does not escape to heap here
    122 		var x M = v // ERROR "v escapes to heap"
    123 		x.M()
    124 	}
    125 	{
    126 		i := 0         // ERROR "moved to heap: i"
    127 		v := M1{&i, 0} // ERROR "&i escapes to heap"
    128 		var x M = v    // ERROR "v escapes to heap"
    129 		mescapes(x)
    130 	}
    131 	{
    132 		i := 0
    133 		v := M1{&i, 0} // ERROR "&i does not escape"
    134 		var x M = v    // ERROR "v does not escape"
    135 		mdoesnotescape(x)
    136 	}
    137 }
    138 
    139 // Tests for type stored directly in iface and with pointer receiver method.
    140 type M2 struct {
    141 	p *int
    142 }
    143 
    144 func (*M2) M() {
    145 }
    146 
    147 func efaceEscape2() {
    148 	{
    149 		i := 0
    150 		v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
    151 		var x M = v  // ERROR "v does not escape"
    152 		_ = x
    153 	}
    154 	{
    155 		i := 0       // ERROR "moved to heap: i"
    156 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
    157 		var x M = v  // ERROR "v escapes to heap"
    158 		sink = x     // ERROR "x escapes to heap"
    159 	}
    160 	{
    161 		i := 0
    162 		v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
    163 		var x M = v  // ERROR "v does not escape"
    164 		v1 := x.(*M2)
    165 		_ = v1
    166 	}
    167 	{
    168 		i := 0       // ERROR "moved to heap: i"
    169 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
    170 		// BAD: v does not escape to heap here
    171 		var x M = v // ERROR "v escapes to heap"
    172 		v1 := x.(*M2)
    173 		sink = v1 // ERROR "v1 escapes to heap"
    174 	}
    175 	{
    176 		i := 0       // ERROR "moved to heap: i"
    177 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape"
    178 		// BAD: v does not escape to heap here
    179 		var x M = v // ERROR "v does not escape"
    180 		v1 := x.(*M2)
    181 		sink = *v1 // ERROR "v1 escapes to heap"
    182 	}
    183 	{
    184 		i := 0       // ERROR "moved to heap: i"
    185 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal does not escape"
    186 		// BAD: v does not escape to heap here
    187 		var x M = v // ERROR "v does not escape"
    188 		v1, ok := x.(*M2)
    189 		sink = *v1 // ERROR "v1 escapes to heap"
    190 		_ = ok
    191 	}
    192 	{
    193 		i := 0       // ERROR "moved to heap: i"
    194 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
    195 		// BAD: v does not escape to heap here
    196 		var x M = v // ERROR "v escapes to heap"
    197 		x.M()
    198 	}
    199 	{
    200 		i := 0       // ERROR "moved to heap: i"
    201 		v := &M2{&i} // ERROR "&i escapes to heap" "&M2 literal escapes to heap"
    202 		var x M = v  // ERROR "v escapes to heap"
    203 		mescapes(x)
    204 	}
    205 	{
    206 		i := 0
    207 		v := &M2{&i} // ERROR "&i does not escape" "&M2 literal does not escape"
    208 		var x M = v  // ERROR "v does not escape"
    209 		mdoesnotescape(x)
    210 	}
    211 }
    212 
    213 type T1 struct {
    214 	p *int
    215 }
    216 
    217 type T2 struct {
    218 	T1 T1
    219 }
    220 
    221 func dotTypeEscape() *T2 { // #11931
    222 	var x interface{}
    223 	x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1 literal does not escape"
    224 	return &T2{
    225 		T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
    226 	}
    227 }
    228 
    229 func dotTypeEscape2() { // #13805, #15796
    230 	{
    231 		i := 0
    232 		j := 0
    233 		var v int
    234 		var ok bool
    235 		var x interface{} = i // ERROR "i does not escape"
    236 		var y interface{} = j // ERROR "j does not escape"
    237 
    238 		*(&v) = x.(int) // ERROR "&v does not escape"
    239 		*(&v), *(&ok) = y.(int) // ERROR "&v does not escape" "&ok does not escape"
    240 	}
    241 	{
    242 		i := 0
    243 		j := 0
    244 		var ok bool
    245 		var x interface{} = i // ERROR "i does not escape"
    246 		var y interface{} = j // ERROR "j does not escape"
    247 
    248 		sink = x.(int)        // ERROR "x.\(int\) escapes to heap"
    249 		sink, *(&ok) = y.(int)     // ERROR "&ok does not escape"
    250 	}
    251 	{
    252 		i := 0 // ERROR "moved to heap: i"
    253 		j := 0 // ERROR "moved to heap: j"
    254 		var ok bool
    255 		var x interface{} = &i // ERROR "&i escapes to heap"
    256 		var y interface{} = &j // ERROR "&j escapes to heap"
    257 
    258 		sink = x.(*int)        // ERROR "x.\(\*int\) escapes to heap"
    259 		sink, *(&ok) = y.(*int)     // ERROR "&ok does not escape"
    260 	}
    261 }
    262