Commit b6b984fc authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: escape unsafe.Pointer conversions when -d=checkptr

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: default avatarKeith Randall <khr@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 9b807915
......@@ -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)
......
......@@ -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
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment