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 closure arguments.
      8 
      9 package escape
     10 
     11 var sink interface{}
     12 
     13 func ClosureCallArgs0() {
     14 	x := 0         // ERROR "moved to heap: x"
     15 	func(p *int) { // ERROR "p does not escape" "func literal does not escape"
     16 		*p = 1
     17 		// BAD: x should not escape to heap here
     18 	}(&x) // ERROR "&x escapes to heap"
     19 }
     20 
     21 func ClosureCallArgs1() {
     22 	x := 0 // ERROR "moved to heap: x"
     23 	for {
     24 		func(p *int) { // ERROR "p does not escape" "func literal does not escape"
     25 			*p = 1
     26 			// BAD: x should not escape to heap here
     27 		}(&x) // ERROR "&x escapes to heap"
     28 	}
     29 }
     30 
     31 func ClosureCallArgs2() {
     32 	for {
     33 		// BAD: x should not escape here
     34 		x := 0         // ERROR "moved to heap: x"
     35 		func(p *int) { // ERROR "p does not escape" "func literal does not escape"
     36 			*p = 1
     37 		}(&x) // ERROR "&x escapes to heap"
     38 	}
     39 }
     40 
     41 func ClosureCallArgs3() {
     42 	x := 0         // ERROR "moved to heap: x"
     43 	func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
     44 		sink = p // ERROR "p escapes to heap"
     45 	}(&x) // ERROR "&x escapes to heap"
     46 }
     47 
     48 func ClosureCallArgs4() {
     49 	// BAD: x should not leak here
     50 	x := 0                  // ERROR "moved to heap: x"
     51 	_ = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
     52 		return p
     53 	}(&x) // ERROR "&x escapes to heap"
     54 }
     55 
     56 func ClosureCallArgs5() {
     57 	x := 0                     // ERROR "moved to heap: x"
     58 	sink = func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape" "\(func literal\)\(&x\) escapes to heap"
     59 		return p
     60 	}(&x) // ERROR "&x escapes to heap"
     61 }
     62 
     63 func ClosureCallArgs6() {
     64 	x := 0         // ERROR "moved to heap: x"
     65 	func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
     66 		sink = &p // ERROR "&p escapes to heap"
     67 	}(&x) // ERROR "&x escapes to heap"
     68 }
     69 
     70 func ClosureCallArgs7() {
     71 	var pp *int
     72 	for {
     73 		x := 0         // ERROR "moved to heap: x"
     74 		func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
     75 			pp = p
     76 		}(&x) // ERROR "&x escapes to heap"
     77 	}
     78 	_ = pp
     79 }
     80 
     81 func ClosureCallArgs8() {
     82 	x := 0               // ERROR "moved to heap: x"
     83 	defer func(p *int) { // ERROR "p does not escape" "func literal does not escape"
     84 		*p = 1
     85 		// BAD: x should not escape to heap here
     86 	}(&x) // ERROR "&x escapes to heap"
     87 }
     88 
     89 func ClosureCallArgs9() {
     90 	// BAD: x should not leak
     91 	x := 0 // ERROR "moved to heap: x"
     92 	for {
     93 		defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
     94 			*p = 1
     95 		}(&x) // ERROR "&x escapes to heap"
     96 	}
     97 }
     98 
     99 func ClosureCallArgs10() {
    100 	for {
    101 		x := 0               // ERROR "moved to heap: x"
    102 		defer func(p *int) { // ERROR "func literal escapes to heap" "p does not escape"
    103 			*p = 1
    104 		}(&x) // ERROR "&x escapes to heap"
    105 	}
    106 }
    107 
    108 func ClosureCallArgs11() {
    109 	x := 0               // ERROR "moved to heap: x"
    110 	defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
    111 		sink = p // ERROR "p escapes to heap"
    112 	}(&x) // ERROR "&x escapes to heap"
    113 }
    114 
    115 func ClosureCallArgs12() {
    116 	// BAD: x should not leak
    117 	x := 0                    // ERROR "moved to heap: x"
    118 	defer func(p *int) *int { // ERROR "leaking param: p to result ~r1" "func literal does not escape"
    119 		return p
    120 	}(&x) // ERROR "&x escapes to heap"
    121 }
    122 
    123 func ClosureCallArgs13() {
    124 	x := 0               // ERROR "moved to heap: x"
    125 	defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
    126 		sink = &p // ERROR "&p escapes to heap"
    127 	}(&x) // ERROR "&x escapes to heap"
    128 }
    129 
    130 func ClosureCallArgs14() {
    131 	x := 0 // ERROR "moved to heap: x"
    132 	// BAD: &x should not escape here
    133 	p := &x                  // ERROR "moved to heap: p" "&x escapes to heap"
    134 	_ = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape"
    135 		return *p
    136 		// BAD: p should not escape here
    137 	}(&p) // ERROR "&p escapes to heap"
    138 }
    139 
    140 func ClosureCallArgs15() {
    141 	x := 0                      // ERROR "moved to heap: x"
    142 	p := &x                     // ERROR "moved to heap: p" "&x escapes to heap"
    143 	sink = func(p **int) *int { // ERROR "leaking param: p to result ~r1 level=1" "func literal does not escape" "\(func literal\)\(&p\) escapes to heap"
    144 		return *p
    145 		// BAD: p should not escape here
    146 	}(&p) // ERROR "&p escapes to heap"
    147 }
    148 
    149 func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape"
    150 	t := s + "YYYY"         // ERROR "escapes to heap"
    151 	return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape"
    152 }
    153 
    154 // See #14409 -- returning part of captured var leaks it.
    155 func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
    156 	return func() string { // ERROR "ClosureLeak1a func literal does not escape"
    157 		return a[0]
    158 	}()
    159 }
    160 
    161 func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape"
    162 	t := s + "YYYY"       // ERROR "escapes to heap"
    163 	c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape"
    164 	return c
    165 }
    166 func ClosureLeak2a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
    167 	return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape"
    168 		return a[0]
    169 	})
    170 }
    171 func ClosureLeak2b(f func() string) string { // ERROR "leaking param: f to result ~r1 level=1"
    172 	return f()
    173 }
    174