github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/test/escape_because.go (about)

     1  // errorcheck -0 -m -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  // Note the doubled -m; this tests the "because" explanations for escapes,
     8  // and is likely to be annoyingly fragile under compiler change.
     9  // As long as the explanations look reasonably sane, meaning eyeball verify output of
    10  //    go build -gcflags '-l -m -m' escape_because.go
    11  // and investigate changes, feel free to update with
    12  //    go run run.go -update_errors -- escape_because.go
    13  
    14  package main
    15  
    16  func main() {
    17  }
    18  
    19  var sink interface{}
    20  
    21  type pair struct {
    22  	x, y *int
    23  }
    24  
    25  type Pairy interface {
    26  	EqualParts() bool
    27  }
    28  
    29  func (p *pair) EqualParts() bool { // ERROR "\(\*pair\).EqualParts p does not escape$"
    30  	return p != nil && (p.x == p.y || *p.x == *p.y)
    31  }
    32  
    33  func f1(p *int) { // ERROR "from \[3\]\*int literal \(array literal element\) at escape_because.go:34$" "from a \(assigned\) at escape_because.go:34$" "from a \(interface-converted\) at escape_because.go:35$" "from sink \(assigned to top level variable\) at escape_because.go:19$" "leaking param: p$"
    34  	a := [3]*int{p, nil, nil}
    35  	sink = a // ERROR "a escapes to heap$" "from sink \(assigned to top level variable\) at escape_because.go:19$"
    36  
    37  }
    38  
    39  func f2(q *int) { // ERROR "from &u \(address-of\) at escape_because.go:43$" "from &u \(interface-converted\) at escape_because.go:43$" "from pair literal \(struct literal element\) at escape_because.go:41$" "from s \(assigned\) at escape_because.go:40$" "from sink \(assigned to top level variable\) at escape_because.go:19$" "from t \(assigned\) at escape_because.go:41$" "from u \(assigned\) at escape_because.go:42$" "leaking param: q$"
    40  	s := q
    41  	t := pair{s, nil}
    42  	u := t    // ERROR "moved to heap: u$"
    43  	sink = &u // ERROR "&u escapes to heap$" "from &u \(interface-converted\) at escape_because.go:43$" "from sink \(assigned to top level variable\) at escape_because.go:19$"
    44  }
    45  
    46  func f3(r *int) interface{} { // ERROR "from \[\]\*int literal \(slice-literal-element\) at escape_because.go:47$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:46$" "leaking param: r to result ~r1 level=-1$"
    47  	c := []*int{r} // ERROR "\[\]\*int literal escapes to heap$" "from c \(assigned\) at escape_because.go:47$" "from c \(interface-converted\) at escape_because.go:48$" "from ~r1 \(return\) at escape_because.go:46$"
    48  	return c       // "return" // ERROR "c escapes to heap$" "from ~r1 \(return\) at escape_because.go:46$"
    49  }
    50  
    51  func f4(a *int, s []*int) int { // ERROR "from \*s \(indirection\) at escape_because.go:51$" "from append\(s, a\) \(appended to slice\) at escape_because.go:52$" "from append\(s, a\) \(appendee slice\) at escape_because.go:52$" "leaking param content: s$" "leaking param: a$"
    52  	s = append(s, a)
    53  	return *(s[0])
    54  }
    55  
    56  func f5(s1, s2 []*int) int { // ERROR "from \*s1 \(indirection\) at escape_because.go:56$" "from \*s2 \(indirection\) at escape_because.go:56$" "from append\(s1, s2...\) \(appended slice...\) at escape_because.go:57$" "from append\(s1, s2...\) \(appendee slice\) at escape_because.go:57$" "leaking param content: s1$" "leaking param content: s2$"
    57  	s1 = append(s1, s2...)
    58  	return *(s1[0])
    59  }
    60  
    61  func f6(x, y *int) bool { // ERROR "f6 x does not escape$" "f6 y does not escape$"
    62  	p := pair{x, y}
    63  	var P Pairy = &p // ERROR "f6 &p does not escape$"
    64  	pp := P.(*pair)
    65  	return pp.EqualParts()
    66  }
    67  
    68  func f7(x map[int]*int, y int) *int { // ERROR "f7 x does not escape$"
    69  	z, ok := x[y]
    70  	if !ok {
    71  		return nil
    72  	}
    73  	return z
    74  }
    75  
    76  func f8(x int, y *int) *int { // ERROR "from ~r2 \(return\) at escape_because.go:76$" "from ~r2 \(returned from recursive function\) at escape_because.go:76$" "leaking param: y$" "moved to heap: x$"
    77  	if x <= 0 {
    78  		return y
    79  	}
    80  	x--
    81  	return f8(*y, &x) // ERROR "&x escapes to heap$" "from y \(arg to recursive call\) at escape_because.go:76$" "from ~r2 \(return\) at escape_because.go:76$" "from ~r2 \(returned from recursive function\) at escape_because.go:76$"
    82  }
    83  
    84  func f9(x int, y ...*int) *int { // ERROR "from y\[0\] \(dot of pointer\) at escape_because.go:86$" "from ~r2 \(return\) at escape_because.go:84$" "from ~r2 \(returned from recursive function\) at escape_because.go:84$" "leaking param content: y$" "leaking param: y to result ~r2 level=1$" "moved to heap: x$"
    85  	if x <= 0 {
    86  		return y[0]
    87  	}
    88  	x--
    89  	return f9(*y[0], &x) // ERROR "&x escapes to heap$" "f9 ... argument does not escape$" "from ... argument \(... arg to recursive call\) at escape_because.go:89$"
    90  }
    91  
    92  func f10(x map[*int]*int, y, z *int) *int { // ERROR "f10 x does not escape$" "from x\[y\] \(key of map put\) at escape_because.go:93$" "from x\[y\] \(value of map put\) at escape_because.go:93$" "leaking param: y$" "leaking param: z$"
    93  	x[y] = z
    94  	return z
    95  }
    96  
    97  func f11(x map[*int]*int, y, z *int) map[*int]*int { // ERROR "f11 x does not escape$" "from map\[\*int\]\*int literal \(map literal key\) at escape_because.go:98$" "from map\[\*int\]\*int literal \(map literal value\) at escape_because.go:98$" "leaking param: y$" "leaking param: z$"
    98  	return map[*int]*int{y: z} // ERROR "from ~r3 \(return\) at escape_because.go:97$" "map\[\*int\]\*int literal escapes to heap$"
    99  }
   100  
   101  // The list below is all of the why-escapes messages seen building the escape analysis tests.
   102  /*
   103     for i in escape*go ; do echo compile $i; go build -gcflags '-l -m -m' $i >& `basename $i .go`.log ; done
   104     grep 'from .* at ' escape*.log | sed -e 's/^.*(\([^()]*\))[^()]*$/\1/' | sort -u
   105  */
   106  // sed RE above assumes that (reason) is the last parenthesized phrase in the line,
   107  // and that none of the reasons contains any parentheses
   108  
   109  /*
   110  ... arg to recursive call
   111  address-of
   112  appended slice...
   113  appended to slice
   114  appendee slice
   115  arg to ...
   116  arg to recursive call
   117  array literal element
   118  array-element-equals
   119  assign-pair
   120  assign-pair-dot-type
   121  assign-pair-func-call
   122  assigned
   123  assigned to top level variable
   124  call part
   125  captured by a closure
   126  closure-var
   127  converted
   128  copied slice
   129  defer func
   130  defer func ...
   131  defer func arg
   132  dot
   133  dot of pointer
   134  dot-equals
   135  fixed-array-index-of
   136  go func
   137  go func ...
   138  go func arg
   139  indirection
   140  interface-converted
   141  key of map put
   142  map literal key
   143  map literal value
   144  parameter to indirect call
   145  passed to function[content escapes]
   146  passed to function[unknown]
   147  passed-to-and-returned-from-function
   148  pointer literal
   149  range
   150  range-deref
   151  receiver in indirect call
   152  return
   153  returned from recursive function
   154  send
   155  slice
   156  slice-element-equals
   157  slice-literal-element
   158  star-dot-equals
   159  star-equals
   160  struct literal element
   161  switch case
   162  too large for stack
   163  value of map put
   164  */
   165  
   166  // Expected, but not yet seen (they may be unreachable):
   167  
   168  /*
   169  append-first-arg
   170  assign-pair-mapr
   171  assign-pair-receive
   172  call receiver
   173  map index
   174  panic
   175  pointer literal [assign]
   176  slice literal element
   177  */