escape_indir.go 3.39 KB
Newer Older
1 2
// errorcheck -0 -m -l

3
// Copyright 2015 The Go Authors. All rights reserved.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test escape analysis when assigning to indirections.

package escape

var sink interface{}

type ConstPtr struct {
	p *int
	c ConstPtr2
	x **ConstPtr
}

type ConstPtr2 struct {
	p *int
	i int
}

func constptr0() {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
	// BAD: i should not escape here
28
	x.p = &i
29 30 31 32 33 34
	_ = x
}

func constptr01() *ConstPtr {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
35
	x.p = &i
36 37 38 39 40 41
	return x
}

func constptr02() ConstPtr {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
42
	x.p = &i
43 44 45 46 47 48
	return *x
}

func constptr03() **ConstPtr {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" "moved to heap: x"
49 50
	x.p = &i
	return &x
51 52 53 54 55
}

func constptr1() {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
56
	x.p = &i
57
	sink = x
58 59 60 61 62
}

func constptr2() {
	i := 0           // ERROR "moved to heap: i"
	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
63
	x.p = &i
64
	sink = *x        // ERROR "\*x escapes to heap"
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
}

func constptr4() *ConstPtr {
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
	*p = *&ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
	return p
}

func constptr5() *ConstPtr {
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
	p1 := &ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
	*p = *p1
	return p
}

// BAD: p should not escape here
81
func constptr6(p *ConstPtr) { // ERROR "leaking param content: p"
82 83 84 85 86 87 88 89
	p1 := &ConstPtr{} // ERROR "&ConstPtr literal does not escape"
	*p1 = *p
	_ = p1
}

func constptr7() **ConstPtr {
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap" "moved to heap: p"
	var tmp ConstPtr2
90
	p1 := &tmp
91
	p.c = *p1
92
	return &p
93 94 95 96 97
}

func constptr8() *ConstPtr {
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
	var tmp ConstPtr2
98
	p.c = *&tmp
99 100 101 102 103 104 105
	return p
}

func constptr9() ConstPtr {
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) does not escape"
	var p1 ConstPtr2
	i := 0    // ERROR "moved to heap: i"
106
	p1.p = &i
107 108 109 110 111 112 113 114
	p.c = p1
	return *p
}

func constptr10() ConstPtr {
	x := &ConstPtr{} // ERROR "moved to heap: x" "&ConstPtr literal escapes to heap"
	i := 0           // ERROR "moved to heap: i"
	var p *ConstPtr
115
	p = &ConstPtr{p: &i, x: &x} // ERROR "&ConstPtr literal does not escape"
116
	var pp **ConstPtr
117
	pp = &p
118 119 120 121 122 123 124
	return **pp
}

func constptr11() *ConstPtr {
	i := 0             // ERROR "moved to heap: i"
	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap"
	p1 := &ConstPtr{}  // ERROR "&ConstPtr literal does not escape"
125
	p1.p = &i
126 127 128 129
	*p = *p1
	return p
}

130
func foo(p **int) { // ERROR "p does not escape"
131 132
	i := 0 // ERROR "moved to heap: i"
	y := p
133
	*y = &i
134 135 136 137
}

func foo1(p *int) { // ERROR "p does not escape"
	i := 0  // ERROR "moved to heap: i"
138 139
	y := &p
	*y = &i
140 141 142 143 144 145 146
}

func foo2() {
	type Z struct {
		f **int
	}
	x := new(int) // ERROR "moved to heap: x" "new\(int\) escapes to heap"
147
	sink = &x
148
	var z Z
149
	z.f = &x
150 151
	p := z.f
	i := 0  // ERROR "moved to heap: i"
152
	*p = &i
153
}
154 155 156 157 158

var global *byte

func f() {
	var x byte    // ERROR "moved to heap: x"
159
	global = &*&x
160
}