Skip to content

Commit b6b984f

Browse files
committed
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 <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 9b80791 commit b6b984f

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,15 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
471471
e.discard(max)
472472

473473
case OCONV, OCONVNOP:
474-
if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR {
474+
if checkPtr(e.curfn) && n.Type.Etype == TUNSAFEPTR && n.Left.Type.IsPtr() {
475+
// When -d=checkptr is enabled, treat
476+
// conversions to unsafe.Pointer as an
477+
// escaping operation. This allows better
478+
// runtime instrumentation, since we can more
479+
// easily detect object boundaries on the heap
480+
// than the stack.
481+
e.assignHeap(n.Left, "conversion to unsafe.Pointer", n)
482+
} else if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR {
475483
e.unsafeValue(k, n.Left)
476484
} else {
477485
e.expr(k, n.Left)

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ opswitch:
951951

952952
case OCONV, OCONVNOP:
953953
n.Left = walkexpr(n.Left, init)
954-
if n.Op == OCONVNOP && Debug_checkptr != 0 && Curfn.Func.Pragma&NoCheckPtr == 0 {
954+
if n.Op == OCONVNOP && checkPtr(Curfn) {
955955
if n.Type.IsPtr() && n.Left.Type.Etype == TUNSAFEPTR { // unsafe.Pointer to *T
956956
n = walkCheckPtrAlignment(n, init)
957957
break
@@ -3971,3 +3971,9 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
39713971
init.Append(mkcall("checkptrArithmetic", nil, init, n, slice))
39723972
return n
39733973
}
3974+
3975+
// checkPtr reports whether pointer checking should be enabled for
3976+
// function fn.
3977+
func checkPtr(fn *Node) bool {
3978+
return Debug_checkptr != 0 && fn.Func.Pragma&NoCheckPtr == 0
3979+
}

0 commit comments

Comments
 (0)