modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/escape_iface.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 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  }