From 46aa8354fa57ab5a4fb133898baf18aafbeb2e88 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Thu, 17 Oct 2019 16:31:19 -0700 Subject: [PATCH] cmd/compile: only escape unsafe.Pointer conversions when -d=checkptr=2 Escaping all unsafe.Pointer conversions for -d=checkptr seems like it might be a little too aggressive to enable for -race/-msan mode, since at least some tests are written to expect unsafe.Pointer conversions to not affect escape analysis. So instead only enable that functionality behind -d=checkptr=2. Updates #22218. Updates #34959. Change-Id: I2f0a774ea5961dabec29bc5b8ebe387a1b90d27b Reviewed-on: https://go-review.googlesource.com/c/go/+/201840 Run-TryBot: Matthew Dempsky Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/escape.go | 4 ++-- src/cmd/compile/internal/gc/main.go | 5 +++++ src/cmd/compile/internal/gc/walk.go | 9 +++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index e25c79998cdbf..66440674d999a 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -471,8 +471,8 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) { e.discard(max) case OCONV, OCONVNOP: - if checkPtr(e.curfn) && n.Type.Etype == TUNSAFEPTR && n.Left.Type.IsPtr() { - // When -d=checkptr is enabled, treat + if checkPtr(e.curfn, 2) && n.Type.Etype == TUNSAFEPTR && n.Left.Type.IsPtr() { + // When -d=checkptr=2 is enabled, treat // conversions to unsafe.Pointer as an // escaping operation. This allows better // runtime instrumentation, since we can more diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index e7131f10a2e6a..771b4fe973f22 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -94,6 +94,11 @@ const debugHelpHeader = `usage: -d arg[,arg]* and arg is [=] const debugHelpFooter = ` is key-specific. +Key "checkptr" supports values: + "0": instrumentation disabled + "1": conversions involving unsafe.Pointer are instrumented + "2": conversions to unsafe.Pointer force heap allocation + Key "pctab" supports values: "pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata" ` diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index ebae392808bb0..4f5fa38a334cf 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 && checkPtr(Curfn) { + if n.Op == OCONVNOP && checkPtr(Curfn, 1) { if n.Type.IsPtr() && n.Left.Type.Etype == TUNSAFEPTR { // unsafe.Pointer to *T n = walkCheckPtrAlignment(n, init) break @@ -3976,7 +3976,8 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node { } // 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 +// function fn at a given level. See debugHelpFooter for defined +// levels. +func checkPtr(fn *Node, level int) bool { + return Debug_checkptr >= level && fn.Func.Pragma&NoCheckPtr == 0 }