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