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