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 when assigning to indirections.
      8 
      9 package escape
     10 
     11 var sink interface{}
     12 
     13 type ConstPtr struct {
     14 	p *int
     15 	c ConstPtr2
     16 	x **ConstPtr
     17 }
     18 
     19 type ConstPtr2 struct {
     20 	p *int
     21 	i int
     22 }
     23 
     24 func constptr0() {
     25 	i := 0           // ERROR "moved to heap: i"
     26 	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
     27 	// BAD: i should not escape here
     28 	x.p = &i // ERROR "&i escapes to heap"
     29 	_ = x
     30 }
     31 
     32 func constptr01() *ConstPtr {
     33 	i := 0           // ERROR "moved to heap: i"
     34 	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
     35 	x.p = &i         // ERROR "&i escapes to heap"
     36 	return x
     37 }
     38 
     39 func constptr02() ConstPtr {
     40 	i := 0           // ERROR "moved to heap: i"
     41 	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
     42 	x.p = &i         // ERROR "&i escapes to heap"
     43 	return *x
     44 }
     45 
     46 func constptr03() **ConstPtr {
     47 	i := 0           // ERROR "moved to heap: i"
     48 	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" "moved to heap: x"
     49 	x.p = &i         // ERROR "&i escapes to heap"
     50 	return &x        // ERROR "&x escapes to heap"
     51 }
     52 
     53 func constptr1() {
     54 	i := 0           // ERROR "moved to heap: i"
     55 	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
     56 	x.p = &i         // ERROR "&i escapes to heap"
     57 	sink = x         // ERROR "x escapes to heap"
     58 }
     59 
     60 func constptr2() {
     61 	i := 0           // ERROR "moved to heap: i"
     62 	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
     63 	x.p = &i         // ERROR "&i escapes to heap"
     64 	sink = *x        // ERROR "\*x escapes to heap"
     65 }
     66 
     67 func constptr4() *ConstPtr {
     68 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
     69 	*p = *&ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
     70 	return p
     71 }
     72 
     73 func constptr5() *ConstPtr {
     74 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
     75 	p1 := &ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
     76 	*p = *p1
     77 	return p
     78 }
     79 
     80 // BAD: p should not escape here
     81 func constptr6(p *ConstPtr) { // ERROR "leaking param content: p"
     82 	p1 := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
     83 	*p1 = *p
     84 	_ = p1
     85 }
     86 
     87 func constptr7() **ConstPtr {
     88 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap" "moved to heap: p"
     89 	var tmp ConstPtr2
     90 	p1 := &tmp // ERROR "&tmp does not escape"
     91 	p.c = *p1
     92 	return &p // ERROR "&p escapes to heap"
     93 }
     94 
     95 func constptr8() *ConstPtr {
     96 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
     97 	var tmp ConstPtr2
     98 	p.c = *&tmp // ERROR "&tmp does not escape"
     99 	return p
    100 }
    101 
    102 func constptr9() ConstPtr {
    103 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) does not escape"
    104 	var p1 ConstPtr2
    105 	i := 0    // ERROR "moved to heap: i"
    106 	p1.p = &i // ERROR "&i escapes to heap"
    107 	p.c = p1
    108 	return *p
    109 }
    110 
    111 func constptr10() ConstPtr {
    112 	x := &ConstPtr{} // ERROR "moved to heap: x" "&ConstPtr literal escapes to heap"
    113 	i := 0           // ERROR "moved to heap: i"
    114 	var p *ConstPtr
    115 	p = &ConstPtr{p: &i, x: &x} // ERROR "&i escapes to heap" "&x escapes to heap" "&ConstPtr literal does not escape"
    116 	var pp **ConstPtr
    117 	pp = &p // ERROR "&p does not escape"
    118 	return **pp
    119 }
    120 
    121 func constptr11() *ConstPtr {
    122 	i := 0             // ERROR "moved to heap: i"
    123 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
    124 	p1 := &ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
    125 	p1.p = &i          // ERROR "&i escapes to heap"
    126 	*p = *p1
    127 	return p
    128 }
    129 
    130 func foo(p **int) { // ERROR "foo p does not escape"
    131 	i := 0 // ERROR "moved to heap: i"
    132 	y := p
    133 	*y = &i // ERROR "&i escapes to heap"
    134 }
    135 
    136 func foo1(p *int) { // ERROR "p does not escape"
    137 	i := 0  // ERROR "moved to heap: i"
    138 	y := &p // ERROR "&p does not escape"
    139 	*y = &i // ERROR "&i escapes to heap"
    140 }
    141 
    142 func foo2() {
    143 	type Z struct {
    144 		f **int
    145 	}
    146 	x := new(int) // ERROR "moved to heap: x" "new\(int\) escapes to heap"
    147 	sink = &x     // ERROR "&x escapes to heap"
    148 	var z Z
    149 	z.f = &x // ERROR "&x does not escape"
    150 	p := z.f
    151 	i := 0  // ERROR "moved to heap: i"
    152 	*p = &i // ERROR "&i escapes to heap"
    153 }
    154 
    155 var global *byte
    156 
    157 func f() {
    158 	var x byte    // ERROR "moved to heap: x"
    159 	global = &*&x // ERROR "&\(\*\(&x\)\) escapes to heap" "&x escapes to heap"
    160 }
    161