diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 57cb59783f145c..ebae392808bb01 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -2392,6 +2392,9 @@ func conv(n *Node, t *types.Type) *Node { // 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) @@ -3915,7 +3918,7 @@ func walkCheckPtrAlignment(n *Node, init *Nodes) *Node { } 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 } @@ -3956,7 +3959,7 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node { 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])) } } } @@ -3968,7 +3971,7 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node { 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 } diff --git a/test/fixedbugs/issue34966.go b/test/fixedbugs/issue34966.go new file mode 100644 index 00000000000000..f920e71a6d7965 --- /dev/null +++ b/test/fixedbugs/issue34966.go @@ -0,0 +1,14 @@ +// 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) }