From b6b984fcff9b6b3b8789c0b628e3226c1edc8b81 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Thu, 17 Oct 2019 12:31:07 -0700 Subject: [PATCH] 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 Reviewed-by: Keith Randall Reviewed-by: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/escape.go | 10 +++++++++- src/cmd/compile/internal/gc/walk.go | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index b855f4a174..e25c79998c 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -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) diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index a9628096e7..57cb59783f 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -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 +} -- 2.50.0