|  | // errorcheck -0 -m -l | 
|  |  | 
|  | // Copyright 2015 The Go Authors. All rights reserved. | 
|  | // 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 | 
|  | x.p = &i | 
|  | _ = x | 
|  | } | 
|  |  | 
|  | func constptr01() *ConstPtr { | 
|  | i := 0           // ERROR "moved to heap: i" | 
|  | x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" | 
|  | x.p = &i | 
|  | return x | 
|  | } | 
|  |  | 
|  | func constptr02() ConstPtr { | 
|  | i := 0           // ERROR "moved to heap: i" | 
|  | x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape" | 
|  | x.p = &i | 
|  | return *x | 
|  | } | 
|  |  | 
|  | func constptr03() **ConstPtr { | 
|  | i := 0           // ERROR "moved to heap: i" | 
|  | x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" "moved to heap: x" | 
|  | x.p = &i | 
|  | return &x | 
|  | } | 
|  |  | 
|  | func constptr1() { | 
|  | i := 0           // ERROR "moved to heap: i" | 
|  | x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" | 
|  | x.p = &i | 
|  | sink = x         // ERROR "x escapes to heap" | 
|  | } | 
|  |  | 
|  | func constptr2() { | 
|  | i := 0           // ERROR "moved to heap: i" | 
|  | x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape" | 
|  | x.p = &i | 
|  | sink = *x        // ERROR "\*x escapes to heap" | 
|  | } | 
|  |  | 
|  | 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 | 
|  | func constptr6(p *ConstPtr) { // ERROR "leaking param content: p" | 
|  | 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 | 
|  | p1 := &tmp | 
|  | p.c = *p1 | 
|  | return &p | 
|  | } | 
|  |  | 
|  | func constptr8() *ConstPtr { | 
|  | p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap" | 
|  | var tmp ConstPtr2 | 
|  | p.c = *&tmp | 
|  | return p | 
|  | } | 
|  |  | 
|  | func constptr9() ConstPtr { | 
|  | p := new(ConstPtr) // ERROR "new\(ConstPtr\) does not escape" | 
|  | var p1 ConstPtr2 | 
|  | i := 0    // ERROR "moved to heap: i" | 
|  | p1.p = &i | 
|  | 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 | 
|  | p = &ConstPtr{p: &i, x: &x} // ERROR "&ConstPtr literal does not escape" | 
|  | var pp **ConstPtr | 
|  | pp = &p | 
|  | 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" | 
|  | p1.p = &i | 
|  | *p = *p1 | 
|  | return p | 
|  | } | 
|  |  | 
|  | func foo(p **int) { // ERROR "foo p does not escape" | 
|  | i := 0 // ERROR "moved to heap: i" | 
|  | y := p | 
|  | *y = &i | 
|  | } | 
|  |  | 
|  | func foo1(p *int) { // ERROR "p does not escape" | 
|  | i := 0  // ERROR "moved to heap: i" | 
|  | y := &p | 
|  | *y = &i | 
|  | } | 
|  |  | 
|  | func foo2() { | 
|  | type Z struct { | 
|  | f **int | 
|  | } | 
|  | x := new(int) // ERROR "moved to heap: x" "new\(int\) escapes to heap" | 
|  | sink = &x     // ERROR "&x escapes to heap" | 
|  | var z Z | 
|  | z.f = &x | 
|  | p := z.f | 
|  | i := 0  // ERROR "moved to heap: i" | 
|  | *p = &i | 
|  | } | 
|  |  | 
|  | var global *byte | 
|  |  | 
|  | func f() { | 
|  | var x byte    // ERROR "moved to heap: x" | 
|  | global = &*&x | 
|  | } |