Skip to content

Commit 50e4508

Browse files
committed
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 <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Trust: Dan Scales <[email protected]>
1 parent 3fa35b5 commit 50e4508

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

src/cmd/compile/internal/typecheck/iexport.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,10 +1456,23 @@ func (w *exportWriter) node(n ir.Node) {
14561456
}
14571457
}
14581458

1459-
// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
1460-
// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
1459+
func isNonEmptyAssign(n ir.Node) bool {
1460+
switch n.Op() {
1461+
case ir.OAS:
1462+
if n.(*ir.AssignStmt).Y != nil {
1463+
return true
1464+
}
1465+
case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1466+
return true
1467+
}
1468+
return false
1469+
}
1470+
1471+
// Caution: stmt will emit more than one node for statement nodes n that have a
1472+
// non-empty n.Ninit and where n is not a non-empty assignment or a node with a natural init
1473+
// section (such as in "if", "for", etc.).
14611474
func (w *exportWriter) stmt(n ir.Node) {
1462-
if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) {
1475+
if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) && !isNonEmptyAssign(n) {
14631476
// can't use stmtList here since we don't want the final OEND
14641477
for _, n := range n.Init() {
14651478
w.stmt(n)
@@ -1495,8 +1508,10 @@ func (w *exportWriter) stmt(n ir.Node) {
14951508
if n.Y != nil {
14961509
w.op(ir.OAS)
14971510
w.pos(n.Pos())
1511+
w.stmtList(n.Init())
14981512
w.expr(n.X)
14991513
w.expr(n.Y)
1514+
w.bool(n.Def)
15001515
}
15011516

15021517
case ir.OASOP:
@@ -1517,8 +1532,10 @@ func (w *exportWriter) stmt(n ir.Node) {
15171532
w.op(ir.OAS2)
15181533
}
15191534
w.pos(n.Pos())
1535+
w.stmtList(n.Init())
15201536
w.exprList(n.Lhs)
15211537
w.exprList(n.Rhs)
1538+
w.bool(n.Def)
15221539

15231540
case ir.ORETURN:
15241541
n := n.(*ir.ReturnStmt)
@@ -2065,8 +2082,10 @@ func (w *exportWriter) expr(n ir.Node) {
20652082
n := n.(*ir.AssignListStmt)
20662083
w.op(ir.OSELRECV2)
20672084
w.pos(n.Pos())
2085+
w.stmtList(n.Init())
20682086
w.exprList(n.Lhs)
20692087
w.exprList(n.Rhs)
2088+
w.bool(n.Def)
20702089

20712090
default:
20722091
base.Fatalf("cannot export %v (%d) node\n"+

src/cmd/compile/internal/typecheck/iimport.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,12 @@ func (r *importReader) node() ir.Node {
16191619
// unreachable - never exported
16201620

16211621
case ir.OAS:
1622-
return ir.NewAssignStmt(r.pos(), r.expr(), r.expr())
1622+
pos := r.pos()
1623+
init := r.stmtList()
1624+
n := ir.NewAssignStmt(pos, r.expr(), r.expr())
1625+
n.SetInit(init)
1626+
n.Def = r.bool()
1627+
return n
16231628

16241629
case ir.OASOP:
16251630
n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
@@ -1636,7 +1641,12 @@ func (r *importReader) node() ir.Node {
16361641
// unreachable - mapped to case OAS2 by exporter
16371642
goto error
16381643
}
1639-
return ir.NewAssignListStmt(r.pos(), op, r.exprList(), r.exprList())
1644+
pos := r.pos()
1645+
init := r.stmtList()
1646+
n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList())
1647+
n.SetInit(init)
1648+
n.Def = r.bool()
1649+
return n
16401650

16411651
case ir.ORETURN:
16421652
return ir.NewReturnStmt(r.pos(), r.exprList())
@@ -1721,7 +1731,12 @@ func (r *importReader) node() ir.Node {
17211731
return n
17221732

17231733
case ir.OSELRECV2:
1724-
return ir.NewAssignListStmt(r.pos(), ir.OSELRECV2, r.exprList(), r.exprList())
1734+
pos := r.pos()
1735+
init := r.stmtList()
1736+
n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList())
1737+
n.SetInit(init)
1738+
n.Def = r.bool()
1739+
return n
17251740

17261741
default:
17271742
base.Fatalf("cannot import %v (%d) node\n"+

src/cmd/compile/internal/walk/order.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,12 @@ func (o *orderState) stmt(n ir.Node) {
941941
if colas {
942942
if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
943943
init = init[1:]
944+
945+
// iimport may have added a default initialization assignment,
946+
// due to how it handles ODCL statements.
947+
if len(init) > 0 && init[0].Op() == ir.OAS && init[0].(*ir.AssignStmt).X == n {
948+
init = init[1:]
949+
}
944950
}
945951
dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
946952
ncas.PtrInit().Append(dcl)

0 commit comments

Comments
 (0)