]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: escape unsafe.Pointer conversions when -d=checkptr
authorMatthew Dempsky <mdempsky@google.com>
Thu, 17 Oct 2019 19:31:07 +0000 (12:31 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 17 Oct 2019 20:09:00 +0000 (20:09 +0000)
This CL tweaks escape analysis to treat unsafe.Pointer(ptr) as an
escaping operation when -d=checkptr is enabled. This allows better
detection of unsafe pointer arithmetic and conversions, because the
runtime checkptr instrumentation can currently only detect object
boundaries for heap objects, not stack objects.

Updates #22218.
Fixes #34959.

Change-Id: I856812cc23582fe4d0d401592583323e95919f28
Reviewed-on: https://go-review.googlesource.com/c/go/+/201781
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/escape.go
src/cmd/compile/internal/gc/walk.go

index b855f4a1748e53e5dc3593b7bfc5ddde71fc4ed1..e25c79998cdbf90bc370c97ff5487a3c6694d44c 100644 (file)
@@ -471,7 +471,15 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                e.discard(max)
 
        case OCONV, OCONVNOP:
-               if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR {
+               if checkPtr(e.curfn) && n.Type.Etype == TUNSAFEPTR && n.Left.Type.IsPtr() {
+                       // When -d=checkptr is enabled, treat
+                       // conversions to unsafe.Pointer as an
+                       // escaping operation. This allows better
+                       // runtime instrumentation, since we can more
+                       // easily detect object boundaries on the heap
+                       // than the stack.
+                       e.assignHeap(n.Left, "conversion to unsafe.Pointer", n)
+               } else if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR {
                        e.unsafeValue(k, n.Left)
                } else {
                        e.expr(k, n.Left)
index a9628096e7fa15f22c9c3aee5820693a3b3bc264..57cb59783f145cd916636ea2a3c81e1ad5a1ff6f 100644 (file)
@@ -951,7 +951,7 @@ opswitch:
 
        case OCONV, OCONVNOP:
                n.Left = walkexpr(n.Left, init)
-               if n.Op == OCONVNOP && Debug_checkptr != 0 && Curfn.Func.Pragma&NoCheckPtr == 0 {
+               if n.Op == OCONVNOP && checkPtr(Curfn) {
                        if n.Type.IsPtr() && n.Left.Type.Etype == TUNSAFEPTR { // unsafe.Pointer to *T
                                n = walkCheckPtrAlignment(n, init)
                                break
@@ -3971,3 +3971,9 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
        init.Append(mkcall("checkptrArithmetic", nil, init, n, slice))
        return n
 }
+
+// checkPtr reports whether pointer checking should be enabled for
+// function fn.
+func checkPtr(fn *Node) bool {
+       return Debug_checkptr != 0 && fn.Func.Pragma&NoCheckPtr == 0
+}