aboutsummaryrefslogtreecommitdiff
path: root/test/escape2.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-02-19 16:27:32 +0300
committerDmitry Vyukov <dvyukov@google.com>2015-03-28 16:15:27 +0000
commitedcc062bdc35a7dd6ac5d33aa85a135b020b72a8 (patch)
treedcf12943f01cb1664af7e009e8403c8fa0875f4b /test/escape2.go
parent8a2545744b2662fc34c117e769f3dbd2f7167d19 (diff)
downloadgo-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.go73
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"
}