From: Dmitry Vyukov Date: Thu, 19 Feb 2015 14:39:17 +0000 (+0300) Subject: test: add tests for escape analysis when assigning to indirections X-Git-Tag: go1.5beta1~1398 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a21537ff74e8d873a9dcf55412a467769ddc3bd5;p=gostls13.git test: add tests for escape analysis when assigning to indirections False positives (var incorrectly escapes) are marked with BAD. Change-Id: I0114d87ee467fe1e3b27642f8c5a04d4a9664211 Reviewed-on: https://go-review.googlesource.com/5295 Reviewed-by: Keith Randall --- diff --git a/test/escape_indir.go b/test/escape_indir.go new file mode 100644 index 0000000000..91aac77d73 --- /dev/null +++ b/test/escape_indir.go @@ -0,0 +1,153 @@ +// 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 +} + +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 +} + +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: 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" +}