aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/walk/builtin.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/walk/builtin.go')
-rw-r--r--src/cmd/compile/internal/walk/builtin.go25
1 files changed, 9 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
index 135eaee6bc..e1a2319e14 100644
--- a/src/cmd/compile/internal/walk/builtin.go
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -647,35 +647,28 @@ func walkRecoverFP(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
}
func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+ ptr := safeExpr(n.X, init)
len := safeExpr(n.Y, init)
fnname := "unsafeslice64"
- argtype := types.Types[types.TINT64]
+ lenType := types.Types[types.TINT64]
// Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
// will be handled by the negative range checks in unsafeslice during runtime.
- if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
+ if ir.ShouldCheckPtr(ir.CurFunc, 1) {
+ fnname = "unsafeslicecheckptr"
+ // for simplicity, unsafeslicecheckptr always uses int64
+ } else if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
fnname = "unsafeslice"
- argtype = types.Types[types.TINT]
+ lenType = types.Types[types.TINT]
}
t := n.Type()
- // Call runtime.unsafeslice[64] to check that the length argument is
- // non-negative and smaller than the max length allowed for the
- // element type.
+ // Call runtime.unsafeslice{,64,checkptr} to check ptr and len.
fn := typecheck.LookupRuntime(fnname)
- init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(len, argtype)))
-
- ptr := walkExpr(n.X, init)
-
- check := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, ptr)
- init.Append(typecheck.Stmt(check))
-
- // TODO(mdempsky): checkptr instrumentation. Maybe merge into length
- // check above, along with nil check? Need to be careful about
- // notinheap pointers though: can't pass them as unsafe.Pointer.
+ init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]), typecheck.Conv(len, lenType)))
h := ir.NewSliceHeaderExpr(n.Pos(), t,
typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),