Skip to content

Commit

Permalink
cmd/compile/internal/gc: unify self-assignment checks in esc.go
Browse files Browse the repository at this point in the history
Move slice self-assign check into isSelfAssign function.
Make debug output consistent for all self-assignment cases.

Change-Id: I0e4cc7b3c1fcaeace7226dd80a0dc1ea97347a55
Reviewed-on: https://go-review.googlesource.com/136276
Run-TryBot: Iskander Sharipov <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Cherry Zhang <[email protected]>
  • Loading branch information
Iskander Sharipov committed Sep 20, 2018
1 parent 9a033bf commit 499fbb1
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 27 deletions.
11 changes: 4 additions & 7 deletions src/cmd/compile/internal/gc/esc.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,10 @@ func (e *EscState) isSliceSelfAssign(dst, src *Node) bool {
// isSelfAssign reports whether assignment from src to dst can
// be ignored by the escape analysis as it's effectively a self-assignment.
func (e *EscState) isSelfAssign(dst, src *Node) bool {
if e.isSliceSelfAssign(dst, src) {
return true
}

// Detect trivial assignments that assign back to the same object.
//
// It covers these cases:
Expand Down Expand Up @@ -890,13 +894,6 @@ opSwitch:

case OAS, OASOP:
// Filter out some no-op assignments for escape analysis.
if e.isSliceSelfAssign(n.Left, n.Right) {
if Debug['m'] != 0 {
Warnl(n.Pos, "%v ignoring self-assignment to %S", e.curfnSym(n), n.Left)
}

break
}
if e.isSelfAssign(n.Left, n.Right) {
if Debug['m'] != 0 {
Warnl(n.Pos, "%v ignoring self-assignment in %S", e.curfnSym(n), n)
Expand Down
20 changes: 10 additions & 10 deletions test/escape2.go
Original file line number Diff line number Diff line change
Expand Up @@ -1602,24 +1602,24 @@ type Buffer struct {
}

func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
}

func (b *Buffer) bar() { // ERROR "leaking param: b$"
b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$"
}

func (b *Buffer) arrayPtr() { // ERROR "\(\*Buffer\).arrayPtr b does not escape"
b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment to b.buf1"
b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment to b.buf1"
b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
}

func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
}

func (b *Buffer) bat() { // ERROR "leaking param content: b$"
Expand All @@ -1629,8 +1629,8 @@ func (b *Buffer) bat() { // ERROR "leaking param content: b$"
}

func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment to \*sp$"
*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment to \*bp$"
*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
}

type StructWithString struct {
Expand Down
20 changes: 10 additions & 10 deletions test/escape2n.go
Original file line number Diff line number Diff line change
Expand Up @@ -1602,24 +1602,24 @@ type Buffer struct {
}

func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
}

func (b *Buffer) bar() { // ERROR "leaking param: b$"
b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$"
}

func (b *Buffer) arrayPtr() { // ERROR "\(\*Buffer\).arrayPtr b does not escape"
b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment to b.buf1"
b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment to b.buf1"
b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
}

func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
}

func (b *Buffer) bat() { // ERROR "leaking param content: b$"
Expand All @@ -1629,8 +1629,8 @@ func (b *Buffer) bat() { // ERROR "leaking param content: b$"
}

func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment to \*sp$"
*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment to \*bp$"
*sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
*bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
}

type StructWithString struct {
Expand Down

0 comments on commit 499fbb1

Please sign in to comment.