| // 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 // ERROR "&i escapes to heap" | 
 | 	_ = x | 
 | } | 
 |  | 
 | func constptr01() *ConstPtr { | 
 | 	i := 0           // ERROR "moved to heap: i" | 
 | 	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" | 
 | 	x.p = &i         // ERROR "&i escapes to heap" | 
 | 	return x | 
 | } | 
 |  | 
 | func constptr02() ConstPtr { | 
 | 	i := 0           // ERROR "moved to heap: i" | 
 | 	x := &ConstPtr{} // ERROR "&ConstPtr literal does not escape" | 
 | 	x.p = &i         // ERROR "&i escapes to heap" | 
 | 	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         // ERROR "&i escapes to heap" | 
 | 	return &x        // ERROR "&x escapes to heap" | 
 | } | 
 |  | 
 | func constptr1() { | 
 | 	i := 0           // ERROR "moved to heap: i" | 
 | 	x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" | 
 | 	x.p = &i         // ERROR "&i escapes to heap" | 
 | 	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         // ERROR "&i escapes to heap" | 
 | 	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 // ERROR "&tmp does not escape" | 
 | 	p.c = *p1 | 
 | 	return &p // ERROR "&p escapes to heap" | 
 | } | 
 |  | 
 | func constptr8() *ConstPtr { | 
 | 	p := new(ConstPtr) // ERROR "new\(ConstPtr\) escapes to heap" | 
 | 	var tmp ConstPtr2 | 
 | 	p.c = *&tmp // ERROR "&tmp does not escape" | 
 | 	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 // ERROR "&i escapes to heap" | 
 | 	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 "&i escapes to heap" "&x escapes to heap" "&ConstPtr literal does not escape" | 
 | 	var pp **ConstPtr | 
 | 	pp = &p // ERROR "&p does not escape" | 
 | 	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          // ERROR "&i escapes to heap" | 
 | 	*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 // ERROR "&i escapes to heap" | 
 | } | 
 |  | 
 | func foo1(p *int) { // ERROR "p does not escape" | 
 | 	i := 0  // ERROR "moved to heap: i" | 
 | 	y := &p // ERROR "&p does not escape" | 
 | 	*y = &i // ERROR "&i escapes to heap" | 
 | } | 
 |  | 
 | 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 // ERROR "&x does not escape" | 
 | 	p := z.f | 
 | 	i := 0  // ERROR "moved to heap: i" | 
 | 	*p = &i // ERROR "&i escapes to heap" | 
 | } | 
 |  | 
 | var global *byte | 
 |  | 
 | func f() { | 
 | 	var x byte    // ERROR "moved to heap: x" | 
 | 	global = &*&x // ERROR "&\(\*\(&x\)\) escapes to heap" "&x escapes to heap" | 
 | } |