Dmitry Vyukov | a21537f | 2015-02-19 17:39:17 +0300 | [diff] [blame] | 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" |
David Chase | 7fbb1b3 | 2015-03-26 16:36:15 -0400 | [diff] [blame] | 57 | sink = x // ERROR "x escapes to heap" |
Dmitry Vyukov | a21537f | 2015-02-19 17:39:17 +0300 | [diff] [blame] | 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" |
David Chase | 7fbb1b3 | 2015-03-26 16:36:15 -0400 | [diff] [blame] | 64 | sink = *x // ERROR "\*x escapes to heap" |
Dmitry Vyukov | a21537f | 2015-02-19 17:39:17 +0300 | [diff] [blame] | 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 |
David Chase | 7fbb1b3 | 2015-03-26 16:36:15 -0400 | [diff] [blame] | 81 | func constptr6(p *ConstPtr) { // ERROR "leaking param content: p" |
Dmitry Vyukov | a21537f | 2015-02-19 17:39:17 +0300 | [diff] [blame] | 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 | } |
David Chase | 7fbb1b3 | 2015-03-26 16:36:15 -0400 | [diff] [blame] | 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 | } |