mirror of
https://github.com/golang/go.git
synced 2024-09-21 10:28:27 +00:00
[dev.regabi] cmd/compile: use explicit block statements for init
For statements like goto that don't need an init, use an explicit block statement instead of forcing them to have one. There is also one call to addinit that is being replaced with a block. That call is the source of much of my confusion regarding init statements: walkstmt calls addinit on a statement, whereas all the other uses of addinit are on expressions. After this CL, they're all expressions. Passes buildall w/ toolstash -cmp. Change-Id: Ifdef9d318c236dc1a7567f9e9ef4a6bedd3fe81f Reviewed-on: https://go-review.googlesource.com/c/go/+/274597 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
ecc8d15bc5
commit
64bc656aed
@ -527,8 +527,8 @@ func inlcalls(fn *ir.Func) {
|
||||
// Turn an OINLCALL into a statement.
|
||||
func inlconv2stmt(inlcall ir.Node) ir.Node {
|
||||
n := ir.NodAt(inlcall.Pos(), ir.OBLOCK, nil, nil)
|
||||
n.SetList(inlcall.Body())
|
||||
n.SetInit(inlcall.Init())
|
||||
n.SetList(inlcall.Init())
|
||||
n.PtrList().AppendNodes(inlcall.PtrBody())
|
||||
return n
|
||||
}
|
||||
|
||||
@ -543,7 +543,7 @@ func inlconv2expr(n ir.Node) ir.Node {
|
||||
// Turn the rlist (with the return values) of the OINLCALL in
|
||||
// n into an expression list lumping the ninit and body
|
||||
// containing the inlined statements on the first list element so
|
||||
// order will be preserved Used in return, oas2func and call
|
||||
// order will be preserved. Used in return, oas2func and call
|
||||
// statements.
|
||||
func inlconv2list(n ir.Node) []ir.Node {
|
||||
if n.Op() != ir.OINLCALL || n.Rlist().Len() == 0 {
|
||||
@ -1330,9 +1330,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
|
||||
|
||||
// dump("Return before substitution", n);
|
||||
case ir.ORETURN:
|
||||
m := nodSym(ir.OGOTO, nil, subst.retlabel)
|
||||
m.PtrInit().Set(subst.list(n.Init()))
|
||||
|
||||
init := subst.list(n.Init())
|
||||
if len(subst.retvars) != 0 && n.List().Len() != 0 {
|
||||
as := ir.Nod(ir.OAS2, nil, nil)
|
||||
|
||||
@ -1352,14 +1350,11 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
|
||||
}
|
||||
|
||||
as = typecheck(as, ctxStmt)
|
||||
m.PtrInit().Append(as)
|
||||
init = append(init, as)
|
||||
}
|
||||
|
||||
typecheckslice(m.Init().Slice(), ctxStmt)
|
||||
m = typecheck(m, ctxStmt)
|
||||
|
||||
// dump("Return after substitution", m);
|
||||
return m
|
||||
init = append(init, nodSym(ir.OGOTO, nil, subst.retlabel))
|
||||
typecheckslice(init, ctxStmt)
|
||||
return ir.NewBlockStmt(base.Pos, init)
|
||||
|
||||
case ir.OGOTO, ir.OLABEL:
|
||||
m := ir.Copy(n)
|
||||
|
@ -147,16 +147,25 @@ func walkstmt(n ir.Node) ir.Node {
|
||||
if n.Typecheck() == 0 {
|
||||
base.Fatalf("missing typecheck: %+v", n)
|
||||
}
|
||||
wascopy := n.Op() == ir.OCOPY
|
||||
init := n.Init()
|
||||
n.PtrInit().Set(nil)
|
||||
n = walkexpr(n, &init)
|
||||
if wascopy && n.Op() == ir.ONAME {
|
||||
if n.Op() == ir.ONAME {
|
||||
// copy rewrote to a statement list and a temp for the length.
|
||||
// Throw away the temp to avoid plain values as statements.
|
||||
n = ir.NodAt(n.Pos(), ir.OBLOCK, nil, nil)
|
||||
n = ir.NewBlockStmt(n.Pos(), init.Slice())
|
||||
init.Set(nil)
|
||||
}
|
||||
if init.Len() > 0 {
|
||||
switch n.Op() {
|
||||
case ir.OAS, ir.OAS2, ir.OBLOCK:
|
||||
n.PtrInit().Prepend(init.Slice()...)
|
||||
|
||||
default:
|
||||
init.Append(n)
|
||||
n = ir.NewBlockStmt(n.Pos(), init.Slice())
|
||||
}
|
||||
}
|
||||
n = addinit(n, init.Slice())
|
||||
|
||||
// special case for a receive where we throw away
|
||||
// the value received.
|
||||
@ -223,29 +232,34 @@ func walkstmt(n ir.Node) ir.Node {
|
||||
}
|
||||
fallthrough
|
||||
case ir.OGO:
|
||||
var init ir.Nodes
|
||||
switch n.Left().Op() {
|
||||
case ir.OPRINT, ir.OPRINTN:
|
||||
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(wrapCall(n.Left(), &init))
|
||||
|
||||
case ir.ODELETE:
|
||||
if mapfast(n.Left().List().First().Type()) == mapslow {
|
||||
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(wrapCall(n.Left(), &init))
|
||||
} else {
|
||||
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(walkexpr(n.Left(), &init))
|
||||
}
|
||||
|
||||
case ir.OCOPY:
|
||||
n.SetLeft(copyany(n.Left(), n.PtrInit(), true))
|
||||
n.SetLeft(copyany(n.Left(), &init, true))
|
||||
|
||||
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
|
||||
if n.Left().Body().Len() > 0 {
|
||||
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(wrapCall(n.Left(), &init))
|
||||
} else {
|
||||
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(walkexpr(n.Left(), &init))
|
||||
}
|
||||
|
||||
default:
|
||||
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
|
||||
n.SetLeft(walkexpr(n.Left(), &init))
|
||||
}
|
||||
if init.Len() > 0 {
|
||||
init.Append(n)
|
||||
n = ir.NewBlockStmt(n.Pos(), init.Slice())
|
||||
}
|
||||
|
||||
case ir.OFOR, ir.OFORUNTIL:
|
||||
|
Loading…
Reference in New Issue
Block a user