]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: mark ... argument to checkptrArithmetic as not escaping
authorKeith Randall <khr@golang.org>
Tue, 14 Jan 2020 17:50:43 +0000 (09:50 -0800)
committerKeith Randall <khr@golang.org>
Fri, 17 Jan 2020 17:38:40 +0000 (17:38 +0000)
Fixes #36516

Change-Id: Ibf4f86fb3a25fa30e0cd54e2dd2e12c60ee75ddb
Reviewed-on: https://go-review.googlesource.com/c/go/+/214679
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/walk.go
test/fixedbugs/issue36516.go [new file with mode: 0644]

index ef88db4742ceb4d8a4a4b7bccbfebcaa43872a21..b8b954c4fc117425fa846762a3744bf3d02c14da 100644 (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
 }
 
diff --git a/test/fixedbugs/issue36516.go b/test/fixedbugs/issue36516.go
new file mode 100644 (file)
index 0000000..1472d4c
--- /dev/null
@@ -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))
+       }
+}