diff options
author | Matthew Dempsky <mdempsky@google.com> | 2023-08-17 14:15:04 -0700 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2023-08-18 11:58:37 +0000 |
commit | 925d2fb36c8e4c9c0e6e240a1621db36c34e5d31 (patch) | |
tree | 2394fb00600d937042524a80e59da78d540e8ffe /test/escape_mutations.go | |
parent | 243c8c0eec20d981d8e76a3aac82f97cca991571 (diff) | |
download | go-925d2fb36c8e4c9c0e6e240a1621db36c34e5d31.tar.gz go-925d2fb36c8e4c9c0e6e240a1621db36c34e5d31.zip |
cmd/compile: restore zero-copy string->[]byte optimization
This CL implements the remainder of the zero-copy string->[]byte
conversion optimization initially attempted in go.dev/cl/520395, but
fixes the tracking of mutations due to ODEREF/ODOTPTR assignments, and
adds more comprehensive tests that I should have included originally.
However, this CL also keeps it behind the -d=zerocopy flag. The next
CL will enable it by default (for easier rollback).
Updates #2205.
Change-Id: Ic330260099ead27fc00e2680a59c6ff23cb63c2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/520599
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'test/escape_mutations.go')
-rw-r--r-- | test/escape_mutations.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/test/escape_mutations.go b/test/escape_mutations.go new file mode 100644 index 0000000000..4365fc1ec3 --- /dev/null +++ b/test/escape_mutations.go @@ -0,0 +1,77 @@ +// errorcheck -0 -m -d=escapemutationscalls,zerocopy -l + +// Copyright 2023 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. + +package p + +import "fmt" + +type B struct { + x int + px *int + pb *B +} + +func F1(b *B) { // ERROR "mutates param: b derefs=0" + b.x = 1 +} + +func F2(b *B) { // ERROR "mutates param: b derefs=1" + *b.px = 1 +} + +func F2a(b *B) { // ERROR "mutates param: b derefs=0" + b.px = nil +} + +func F3(b *B) { // ERROR "leaking param: b" + fmt.Println(b) // ERROR "\.\.\. argument does not escape" +} + +func F4(b *B) { // ERROR "leaking param content: b" + fmt.Println(*b) // ERROR "\.\.\. argument does not escape" "\*b escapes to heap" +} + +func F4a(b *B) { // ERROR "leaking param content: b" "mutates param: b derefs=0" + b.x = 2 + fmt.Println(*b) // ERROR "\.\.\. argument does not escape" "\*b escapes to heap" +} + +func F5(b *B) { // ERROR "leaking param: b" + sink = b +} + +func F6(b *B) int { // ERROR "b does not escape, mutate, or call" + return b.x +} + +var sink any + +func M() { + var b B // ERROR "moved to heap: b" + F1(&b) + F2(&b) + F2a(&b) + F3(&b) + F4(&b) +} + +func g(s string) { // ERROR "s does not escape, mutate, or call" + sink = &([]byte(s))[10] // ERROR "\(\[\]byte\)\(s\) escapes to heap" +} + +func h(out []byte, s string) { // ERROR "mutates param: out derefs=0" "s does not escape, mutate, or call" + copy(out, []byte(s)) // ERROR "zero-copy string->\[\]byte conversion" "\(\[\]byte\)\(s\) does not escape" +} + +func i(s string) byte { // ERROR "s does not escape, mutate, or call" + p := []byte(s) // ERROR "zero-copy string->\[\]byte conversion" "\(\[\]byte\)\(s\) does not escape" + return p[20] +} + +func j(s string, x byte) { // ERROR "s does not escape, mutate, or call" + p := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape" + p[20] = x +} |