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