[dev.typeparams] cmd/compile: allow typecheck of OCHECKNIL

This CL makes OCHECKNIL typecheckable. Simplifies IR construction code
slightly, and gives one convenient place to check for misuse.

Change-Id: I280b8e47eddcac12947a41d6f911b25bc12a66bf
Reviewed-on: https://go-review.googlesource.com/c/go/+/330194
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2021-06-22 18:15:21 -07:00
parent c4e0c652fb
commit 493e177639
5 changed files with 19 additions and 19 deletions

View file

@ -237,6 +237,15 @@ func plural(n int) string {
return "s"
}
// tcCheckNil typechecks an OCHECKNIL node.
func tcCheckNil(n *ir.UnaryExpr) ir.Node {
n.X = Expr(n.X)
if !n.X.Type().IsPtrShaped() {
base.FatalfAt(n.Pos(), "%L is not pointer shaped", n.X)
}
return n
}
// tcFor typechecks an OFOR node.
func tcFor(n *ir.ForStmt) ir.Node {
Stmts(n.Init())

View file

@ -876,6 +876,10 @@ func typecheck1(n ir.Node, top int) ir.Node {
n := n.(*ir.TailCallStmt)
return n
case ir.OCHECKNIL:
n := n.(*ir.UnaryExpr)
return tcCheckNil(n)
case ir.OSELECT:
tcSelect(n.(*ir.SelectStmt))
return n

View file

@ -677,9 +677,8 @@ func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
ptr := walkExpr(n.X, init)
c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, ptr)
c.SetTypecheck(1)
init.Append(c)
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

View file

@ -178,11 +178,9 @@ func walkCallPart(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
n.X = cheapExpr(n.X, init)
n.X = walkExpr(n.X, nil)
tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
c := ir.NewUnaryExpr(base.Pos, ir.OCHECKNIL, tab)
c.SetTypecheck(1)
init.Append(c)
tab := ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X)
check := ir.NewUnaryExpr(base.Pos, ir.OCHECKNIL, tab)
init.Append(typecheck.Stmt(check))
}
typ := typecheck.PartialCallType(n)

View file

@ -762,7 +762,7 @@ func (o *orderState) stmt(n ir.Node) {
o.out = append(o.out, n)
o.cleanTemp(t)
case ir.OCLOSE, ir.ORECV:
case ir.OCHECKNIL, ir.OCLOSE, ir.OPANIC, ir.ORECV:
n := n.(*ir.UnaryExpr)
t := o.markTemp()
n.X = o.expr(n.X, nil)
@ -835,16 +835,6 @@ func (o *orderState) stmt(n ir.Node) {
orderBlock(&n.Else, o.free)
o.out = append(o.out, n)
case ir.OPANIC:
n := n.(*ir.UnaryExpr)
t := o.markTemp()
n.X = o.expr(n.X, nil)
if !n.X.Type().IsEmptyInterface() {
base.FatalfAt(n.Pos(), "bad argument to panic: %L", n.X)
}
o.out = append(o.out, n)
o.cleanTemp(t)
case ir.ORANGE:
// n.Right is the expression being ranged over.
// order it, and then make a copy if we need one.