mirror of
https://github.com/golang/go
synced 2024-09-04 15:34:21 +00:00
[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:
parent
c4e0c652fb
commit
493e177639
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue