From 9568126f350b10163155045445cb149323a2b5c8 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 30 Jan 2015 09:14:13 +0300 Subject: cmd/gc: allocate buffers for non-escaping string conversions on stack Support the following conversions in escape analysis: []rune("foo") []byte("foo") string([]rune{}) If the result does not escape, allocate temp buffer on stack and pass it to runtime functions. Change-Id: I1d075907eab8b0109ad7ad1878104b02b3d5c690 Reviewed-on: https://go-review.googlesource.com/3590 Reviewed-by: Russ Cox --- test/escape2.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'test/escape2.go') diff --git a/test/escape2.go b/test/escape2.go index 8c50277e9d..947dcc9515 100644 --- a/test/escape2.go +++ b/test/escape2.go @@ -212,7 +212,7 @@ func foo21() func() int { func foo21a() func() int { x := 42 // ERROR "moved to heap: x" return func() int { // ERROR "func literal escapes to heap" - x++ // ERROR "&x escapes to heap" + x++ // ERROR "&x escapes to heap" return x } } @@ -1560,14 +1560,14 @@ func ptrlitNoescape() { func ptrlitNoEscape2() { // Literal does not escape, but element does. - i := 0 // ERROR "moved to heap: i" + i := 0 // ERROR "moved to heap: i" x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i escapes to heap" sink = *x } func ptrlitEscape() { // Both literal and element escape. - i := 0 // ERROR "moved to heap: i" + i := 0 // ERROR "moved to heap: i" x := &Lit{&i} // ERROR "&Lit literal escapes to heap" "&i escapes to heap" sink = x } @@ -1619,7 +1619,7 @@ type StructWithString struct { // to just x, and thus &i looks escaping. func fieldFlowTracking() { var x StructWithString - i := 0 // ERROR "moved to heap: i" + i := 0 // ERROR "moved to heap: i" x.p = &i // ERROR "&i escapes to heap" sink = x.s } @@ -1703,3 +1703,51 @@ func intstring2() { s := string(x) // ERROR "string\(x\) escapes to heap" "moved to heap: s" sink = &s // ERROR "&s escapes to heap" } + +func stringtoslicebyte0() { + s := "foo" + x := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape" + _ = x +} + +func stringtoslicebyte1() []byte { + s := "foo" + return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap" +} + +func stringtoslicebyte2() { + s := "foo" + sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap" +} + +func stringtoslicerune0() { + s := "foo" + x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape" + _ = x +} + +func stringtoslicerune1() []rune { + s := "foo" + return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap" +} + +func stringtoslicerune2() { + s := "foo" + sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap" +} + +func slicerunetostring0() { + r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape" + s := string(r) // ERROR "string\(r\) does not escape" + _ = s +} + +func slicerunetostring1() string { + r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape" + return string(r) // ERROR "string\(r\) escapes to heap" +} + +func slicerunetostring2() { + r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape" + sink = string(r) // ERROR "string\(r\) escapes to heap" +} -- cgit v1.2.1