mirror of
https://github.com/golang/go
synced 2024-11-23 05:30:07 -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:
parent
574c286607
commit
316fd8cc4a
@ -1705,7 +1705,6 @@ func mkdotargslice(typ *types.Type, args []*Node, init *Nodes, ddd *Node) *Node
|
|||||||
if ddd != nil {
|
if ddd != nil {
|
||||||
esc = ddd.Esc
|
esc = ddd.Esc
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
n := nodnil()
|
n := nodnil()
|
||||||
n.Type = typ
|
n.Type = typ
|
||||||
@ -1740,6 +1739,9 @@ func walkCall(n *Node, init *Nodes) {
|
|||||||
// then assign the remaining arguments as a slice.
|
// then assign the remaining arguments as a slice.
|
||||||
if nf := params.NumFields(); nf > 0 {
|
if nf := params.NumFields(); nf > 0 {
|
||||||
if last := params.Field(nf - 1); last.IsDDD() && !n.IsDDD() {
|
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:]
|
tail := args[nf-1:]
|
||||||
slice := mkdotargslice(last.Type, tail, init, n.Right)
|
slice := mkdotargslice(last.Type, tail, init, n.Right)
|
||||||
// Allow immediate GC.
|
// Allow immediate GC.
|
||||||
@ -4067,11 +4069,15 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
|
|||||||
|
|
||||||
n = cheapexpr(n, init)
|
n = cheapexpr(n, init)
|
||||||
|
|
||||||
slice := mkdotargslice(types.NewSlice(types.Types[TUNSAFEPTR]), originals, init, nil)
|
ddd := nodl(n.Pos, ODDDARG, nil, nil)
|
||||||
slice.Esc = EscNone
|
ddd.Type = types.NewPtr(types.NewArray(types.Types[TUNSAFEPTR], int64(len(originals))))
|
||||||
slice.SetTransient(true)
|
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))
|
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
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
test/fixedbugs/issue36516.go
Normal file
27
test/fixedbugs/issue36516.go
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user