modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/escape_slice.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 slices.
     8  
     9  package escape
    10  
    11  import (
    12  	"os"
    13  	"strings"
    14  )
    15  
    16  var sink interface{}
    17  
    18  func slice0() {
    19  	var s []*int
    20  	// BAD: i should not escape
    21  	i := 0            // ERROR "moved to heap: i"
    22  	s = append(s, &i) // ERROR "&i escapes to heap"
    23  	_ = s
    24  }
    25  
    26  func slice1() *int {
    27  	var s []*int
    28  	i := 0            // ERROR "moved to heap: i"
    29  	s = append(s, &i) // ERROR "&i escapes to heap"
    30  	return s[0]
    31  }
    32  
    33  func slice2() []*int {
    34  	var s []*int
    35  	i := 0            // ERROR "moved to heap: i"
    36  	s = append(s, &i) // ERROR "&i escapes to heap"
    37  	return s
    38  }
    39  
    40  func slice3() *int {
    41  	var s []*int
    42  	i := 0            // ERROR "moved to heap: i"
    43  	s = append(s, &i) // ERROR "&i escapes to heap"
    44  	for _, p := range s {
    45  		return p
    46  	}
    47  	return nil
    48  }
    49  
    50  func slice4(s []*int) { // ERROR "s does not escape"
    51  	i := 0    // ERROR "moved to heap: i"
    52  	s[0] = &i // ERROR "&i escapes to heap"
    53  }
    54  
    55  func slice5(s []*int) { // ERROR "s does not escape"
    56  	if s != nil {
    57  		s = make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
    58  	}
    59  	i := 0    // ERROR "moved to heap: i"
    60  	s[0] = &i // ERROR "&i escapes to heap"
    61  }
    62  
    63  func slice6() {
    64  	s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
    65  	// BAD: i should not escape
    66  	i := 0    // ERROR "moved to heap: i"
    67  	s[0] = &i // ERROR "&i escapes to heap"
    68  	_ = s
    69  }
    70  
    71  func slice7() *int {
    72  	s := make([]*int, 10) // ERROR "make\(\[\]\*int, 10\) does not escape"
    73  	i := 0                // ERROR "moved to heap: i"
    74  	s[0] = &i             // ERROR "&i escapes to heap"
    75  	return s[0]
    76  }
    77  
    78  func slice8() {
    79  	i := 0
    80  	s := []*int{&i} // ERROR "&i does not escape" "literal does not escape"
    81  	_ = s
    82  }
    83  
    84  func slice9() *int {
    85  	i := 0          // ERROR "moved to heap: i"
    86  	s := []*int{&i} // ERROR "&i escapes to heap" "literal does not escape"
    87  	return s[0]
    88  }
    89  
    90  func slice10() []*int {
    91  	i := 0          // ERROR "moved to heap: i"
    92  	s := []*int{&i} // ERROR "&i escapes to heap" "literal escapes to heap"
    93  	return s
    94  }
    95  
    96  func envForDir(dir string) []string { // ERROR "dir does not escape"
    97  	env := os.Environ()
    98  	return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string literal does not escape"
    99  }
   100  
   101  func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r2 level=0"
   102  NextVar:
   103  	for _, inkv := range in {
   104  		k := strings.SplitAfterN(inkv, "=", 2)[0]
   105  		for i, outkv := range out {
   106  			if strings.HasPrefix(outkv, k) {
   107  				out[i] = inkv
   108  				continue NextVar
   109  			}
   110  		}
   111  		out = append(out, inkv)
   112  	}
   113  	return out
   114  }
   115  
   116  const (
   117  	IPv4len = 4
   118  	IPv6len = 16
   119  )
   120  
   121  var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
   122  
   123  func IPv4(a, b, c, d byte) IP {
   124  	p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap"
   125  	copy(p, v4InV6Prefix)
   126  	p[12] = a
   127  	p[13] = b
   128  	p[14] = c
   129  	p[15] = d
   130  	return p
   131  }
   132  
   133  type IP []byte
   134  
   135  type IPAddr struct {
   136  	IP   IP
   137  	Zone string // IPv6 scoped addressing zone
   138  }
   139  
   140  type resolveIPAddrTest struct {
   141  	network       string
   142  	litAddrOrName string
   143  	addr          *IPAddr
   144  	err           error
   145  }
   146  
   147  var resolveIPAddrTests = []resolveIPAddrTest{
   148  	{"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
   149  	{"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
   150  	{"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
   151  }
   152  
   153  func setupTestData() {
   154  	resolveIPAddrTests = append(resolveIPAddrTests,
   155  		[]resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest literal does not escape"
   156  			{"ip",
   157  				"localhost",
   158  				&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
   159  				nil},
   160  			{"ip4",
   161  				"localhost",
   162  				&IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap"
   163  				nil},
   164  		}...)
   165  }