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
const debugHelpFooter = `
<value> 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"
`
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
}
// 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
}