diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2015-02-19 16:27:32 +0300 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2015-03-28 16:15:27 +0000 |
commit | edcc062bdc35a7dd6ac5d33aa85a135b020b72a8 (patch) | |
tree | dcf12943f01cb1664af7e009e8403c8fa0875f4b /test/escape2.go | |
parent | 8a2545744b2662fc34c117e769f3dbd2f7167d19 (diff) | |
download | go-edcc062bdc35a7dd6ac5d33aa85a135b020b72a8.tar.gz go-edcc062bdc35a7dd6ac5d33aa85a135b020b72a8.zip |
test: add tests for escape analysis of interface conversions
The false positives (var incorrectly escapes) are marked with BAD.
Change-Id: If64fabb6ea96de44a1177d9ab12e2ccc579fe0c4
Reviewed-on: https://go-review.googlesource.com/5294
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'test/escape2.go')
-rw-r--r-- | test/escape2.go | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/test/escape2.go b/test/escape2.go index 69c5913db0..591e6e1469 100644 --- a/test/escape2.go +++ b/test/escape2.go @@ -475,12 +475,13 @@ func foo66() { func foo67() { var mv MV - foo63(mv) + foo63(mv) // ERROR "mv does not escape" } func foo68() { var mv MV - foo64(mv) // escapes but it's an int so irrelevant + // escapes but it's an int so irrelevant + foo64(mv) // ERROR "mv escapes to heap" } func foo69(m M) { // ERROR "leaking param: m" @@ -488,7 +489,7 @@ func foo69(m M) { // ERROR "leaking param: m" } func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m" - m = mv1 + m = mv1 // ERROR "mv1 escapes to heap" foo64(m) } @@ -619,62 +620,62 @@ func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not esca } func foo75(z *int) { // ERROR "z does not escape" - myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo75a(z *int) { // ERROR "z does not escape" - myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo75esc(z *int) { // ERROR "leaking param: z" - gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo75aesc(z *int) { // ERROR "z does not escape" var ppi **interface{} // assignments to pointer dereferences lose track - *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" + *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo75aesc1(z *int) { // ERROR "z does not escape" - sink = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" + sink = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "myprint1\(z, 1, 2, 3\) escapes to heap" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } // BAD: z does not escape here func foo76(z *int) { // ERROR "leaking param: z" - myprint(nil, z) // ERROR "[.][.][.] argument does not escape" + myprint(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" } // BAD: z does not escape here func foo76a(z *int) { // ERROR "leaking param: z" - myprint1(nil, z) // ERROR "[.][.][.] argument does not escape" + myprint1(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" } func foo76b() { - myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo76c() { - myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo76d() { - defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo76e() { - defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" + defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } func foo76f() { for { // TODO: This one really only escapes its scope, but we don't distinguish yet. - defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" + defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } } func foo76g() { for { - defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" + defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" } } @@ -692,7 +693,7 @@ func foo77b(z []interface{}) { // ERROR "leaking param: z" } func foo77c(z []interface{}) { // ERROR "leaking param: z" - sink = myprint1(nil, z...) + sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z\.\.\.\) escapes to heap" } func dotdotdot() { @@ -1151,16 +1152,16 @@ L100: func foo121() { for i := 0; i < 10; i++ { - defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" - go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" + defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" "i escapes to heap" + go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap" "i escapes to heap" } } // same as foo121 but check across import func foo121b() { for i := 0; i < 10; i++ { - defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" - go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" + defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" "i escapes to heap" + go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" "i escapes to heap" } } @@ -1347,7 +1348,7 @@ func foo140() interface{} { T *T } t := &T{} // ERROR "&T literal escapes to heap" - return U{ + return U{ // ERROR "U literal escapes to heap" X: t.X, T: t, } @@ -1582,14 +1583,14 @@ func ptrlitNoEscape2() { // Literal does not escape, but element does. i := 0 // ERROR "moved to heap: i" x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i escapes to heap" - sink = *x + sink = *x // ERROR "\*x escapes to heap" } func ptrlitEscape() { // Both literal and element escape. i := 0 // ERROR "moved to heap: i" x := &Lit{&i} // ERROR "&Lit literal escapes to heap" "&i escapes to heap" - sink = x + sink = x // ERROR "x escapes to heap" } // self-assignments @@ -1621,7 +1622,7 @@ func (b *Buffer) baz() { // ERROR "b does not escape" func (b *Buffer) bat() { // ERROR "leaking param: b" o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap" o.buf1 = b.buf1[1:2] - sink = o + sink = o // ERROR "o escapes to heap" } func quux(sp *string, bp *[]byte) { // ERROR "sp does not escape" "bp does not escape" @@ -1639,9 +1640,9 @@ type StructWithString struct { // to just x, and thus &i looks escaping. func fieldFlowTracking() { var x StructWithString - i := 0 // ERROR "moved to heap: i" - x.p = &i // ERROR "&i escapes to heap" - sink = x.s + i := 0 // ERROR "moved to heap: i" + x.p = &i // ERROR "&i escapes to heap" + sink = x.s // ERROR "x.s escapes to heap" } // String operations. @@ -1670,7 +1671,7 @@ func slicebytetostring3() { b := make([]byte, 20) // ERROR "does not escape" s := string(b) // ERROR "string\(b\) escapes to heap" s1 := s[0:1] - sink = s1 + sink = s1 // ERROR "s1 escapes to heap" } func addstr0() { @@ -1700,7 +1701,7 @@ func addstr3() { s1 := "b" s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap" s2 := s[0:1] - sink = s2 + sink = s2 // ERROR "s2 escapes to heap" } func intstring0() bool { @@ -1777,7 +1778,7 @@ func makemap0() { m[0] = 0 m[1]++ delete(m, 1) - sink = m[0] + sink = m[0] // ERROR "m\[0\] escapes to heap" } func makemap1() map[int]int { @@ -1786,5 +1787,13 @@ func makemap1() map[int]int { func makemap2() { m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap" - sink = m + sink = m // ERROR "m escapes to heap" +} + +func nonescapingEface(m map[interface{}]bool) bool { // ERROR "m does not escape" + return m["foo"] // ERROR `"foo" does not escape` +} + +func nonescapingIface(m map[M]bool) bool { // ERROR "m does not escape" + return m[MV(0)] // ERROR "MV\(0\) does not escape" } |