// convnop converts node n to type t using the OCONVNOP op
// and typechecks the result with ctxExpr.
func convnop(n *Node, t *types.Type) *Node {
+ if types.Identical(n.Type, t) {
+ return n
+ }
n = nod(OCONVNOP, n, nil)
n.Type = t
n = typecheck(n, ctxExpr)
}
n.Left = cheapexpr(n.Left, init)
- init.Append(mkcall("checkptrAlignment", nil, init, n.Left, typename(n.Type.Elem())))
+ init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left, types.Types[TUNSAFEPTR]), typename(n.Type.Elem())))
return n
}
case OCONVNOP:
if n.Left.Type.Etype == TUNSAFEPTR {
n.Left = cheapexpr(n.Left, init)
- originals = append(originals, n.Left)
+ originals = append(originals, convnop(n.Left, types.Types[TUNSAFEPTR]))
}
}
}
slice.Esc = EscNone
slice.SetTransient(true)
- init.Append(mkcall("checkptrArithmetic", nil, init, n, slice))
+ init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[TUNSAFEPTR]), slice))
return n
}
--- /dev/null
+// compile -d=checkptr
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type ptr unsafe.Pointer
+
+func f(p ptr) *int { return (*int)(p) }
+func g(p ptr) ptr { return ptr(uintptr(p) + 1) }