1
0
mirror of https://github.com/golang/go synced 2024-11-23 04:40:09 -07:00

cmd/compile: mark ... argument to checkptrArithmetic as not escaping

Fixes #36516

Change-Id: Ibf4f86fb3a25fa30e0cd54e2dd2e12c60ee75ddb
Reviewed-on: https://go-review.googlesource.com/c/go/+/214679
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Keith Randall 2020-01-14 09:50:43 -08:00
parent 574c286607
commit 316fd8cc4a
2 changed files with 37 additions and 4 deletions

View File

@ -1705,7 +1705,6 @@ func mkdotargslice(typ *types.Type, args []*Node, init *Nodes, ddd *Node) *Node
if ddd != nil {
esc = ddd.Esc
}
if len(args) == 0 {
n := nodnil()
n.Type = typ
@ -1740,6 +1739,9 @@ func walkCall(n *Node, init *Nodes) {
// then assign the remaining arguments as a slice.
if nf := params.NumFields(); nf > 0 {
if last := params.Field(nf - 1); last.IsDDD() && !n.IsDDD() {
// The callsite does not use a ..., but the called function is declared
// with a final argument that has a ... . Build the slice that we will
// pass as the ... argument.
tail := args[nf-1:]
slice := mkdotargslice(last.Type, tail, init, n.Right)
// Allow immediate GC.
@ -4067,11 +4069,15 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
n = cheapexpr(n, init)
slice := mkdotargslice(types.NewSlice(types.Types[TUNSAFEPTR]), originals, init, nil)
slice.Esc = EscNone
slice.SetTransient(true)
ddd := nodl(n.Pos, ODDDARG, nil, nil)
ddd.Type = types.NewPtr(types.NewArray(types.Types[TUNSAFEPTR], int64(len(originals))))
ddd.Esc = EscNone
slice := mkdotargslice(types.NewSlice(types.Types[TUNSAFEPTR]), originals, init, ddd)
init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[TUNSAFEPTR]), slice))
// TODO(khr): Mark backing store of slice as dead. This will allow us to reuse
// the backing store for multiple calls to checkptrArithmetic.
return n
}

View File

@ -0,0 +1,27 @@
// +build linux,amd64
// run -race
// Copyright 2020 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 main
import (
"fmt"
"testing"
"unsafe"
)
var buf [2]byte
var x unsafe.Pointer = unsafe.Pointer(&buf[0])
func main() {
n := testing.AllocsPerRun(1000, func() {
x = unsafe.Pointer(uintptr(x) + 1)
x = unsafe.Pointer(uintptr(x) - 1)
})
if n > 0 {
panic(fmt.Sprintf("too many allocations; want 0 got %f", n))
}
}