1
0
mirror of https://github.com/golang/go synced 2024-11-17 05:54:46 -07:00

cmd/compile: fix import/export of Init and Def fields.

Change so that the Init and Def fields of assignments and OSELREVC2
nodes are exported/imported properly.

A quirk of iimport.go is that it automatically converts an ODCL node to
an ODCL/OAS sequence (where the OAS is to just zero out the declared
variable). Given that the Inits are properly fixed, o.stmt needs
adjustment for the OSELRECV2 case to skip over the new OAS nodes that
are inserted only on re-import.

Change-Id: Ic38017efca4b7ca9b3952ffbbfca067380902b7a
Reviewed-on: https://go-review.googlesource.com/c/go/+/350809
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
This commit is contained in:
Dan Scales 2021-09-17 12:18:19 -07:00
parent 3fa35b5f97
commit 50e4508269
3 changed files with 46 additions and 6 deletions

View File

@ -1456,10 +1456,23 @@ func (w *exportWriter) node(n ir.Node) {
}
}
// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
func isNonEmptyAssign(n ir.Node) bool {
switch n.Op() {
case ir.OAS:
if n.(*ir.AssignStmt).Y != nil {
return true
}
case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
return true
}
return false
}
// Caution: stmt will emit more than one node for statement nodes n that have a
// non-empty n.Ninit and where n is not a non-empty assignment or a node with a natural init
// section (such as in "if", "for", etc.).
func (w *exportWriter) stmt(n ir.Node) {
if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) {
if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) && !isNonEmptyAssign(n) {
// can't use stmtList here since we don't want the final OEND
for _, n := range n.Init() {
w.stmt(n)
@ -1495,8 +1508,10 @@ func (w *exportWriter) stmt(n ir.Node) {
if n.Y != nil {
w.op(ir.OAS)
w.pos(n.Pos())
w.stmtList(n.Init())
w.expr(n.X)
w.expr(n.Y)
w.bool(n.Def)
}
case ir.OASOP:
@ -1517,8 +1532,10 @@ func (w *exportWriter) stmt(n ir.Node) {
w.op(ir.OAS2)
}
w.pos(n.Pos())
w.stmtList(n.Init())
w.exprList(n.Lhs)
w.exprList(n.Rhs)
w.bool(n.Def)
case ir.ORETURN:
n := n.(*ir.ReturnStmt)
@ -2065,8 +2082,10 @@ func (w *exportWriter) expr(n ir.Node) {
n := n.(*ir.AssignListStmt)
w.op(ir.OSELRECV2)
w.pos(n.Pos())
w.stmtList(n.Init())
w.exprList(n.Lhs)
w.exprList(n.Rhs)
w.bool(n.Def)
default:
base.Fatalf("cannot export %v (%d) node\n"+

View File

@ -1619,7 +1619,12 @@ func (r *importReader) node() ir.Node {
// unreachable - never exported
case ir.OAS:
return ir.NewAssignStmt(r.pos(), r.expr(), r.expr())
pos := r.pos()
init := r.stmtList()
n := ir.NewAssignStmt(pos, r.expr(), r.expr())
n.SetInit(init)
n.Def = r.bool()
return n
case ir.OASOP:
n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
@ -1636,7 +1641,12 @@ func (r *importReader) node() ir.Node {
// unreachable - mapped to case OAS2 by exporter
goto error
}
return ir.NewAssignListStmt(r.pos(), op, r.exprList(), r.exprList())
pos := r.pos()
init := r.stmtList()
n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList())
n.SetInit(init)
n.Def = r.bool()
return n
case ir.ORETURN:
return ir.NewReturnStmt(r.pos(), r.exprList())
@ -1721,7 +1731,12 @@ func (r *importReader) node() ir.Node {
return n
case ir.OSELRECV2:
return ir.NewAssignListStmt(r.pos(), ir.OSELRECV2, r.exprList(), r.exprList())
pos := r.pos()
init := r.stmtList()
n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList())
n.SetInit(init)
n.Def = r.bool()
return n
default:
base.Fatalf("cannot import %v (%d) node\n"+

View File

@ -941,6 +941,12 @@ func (o *orderState) stmt(n ir.Node) {
if colas {
if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
init = init[1:]
// iimport may have added a default initialization assignment,
// due to how it handles ODCL statements.
if len(init) > 0 && init[0].Op() == ir.OAS && init[0].(*ir.AssignStmt).X == n {
init = init[1:]
}
}
dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
ncas.PtrInit().Append(dcl)