[dev.regabi] cmd/compile: remove CommStmt.List

Package syntax's parser already ensures that select communication
clauses only have one statement, so there's no need for ir's CommStmt
to need to represent more than one. Instead, noder can just directly
populate Comm in the first place.

Incidentally, this also revealed a latent issue in the inline-body
exporter: we were exporting List (where the case statement is before
type-checking), rather than Comm (where the case statement would be
after type-checking, when export happens).

Passes toolstash -cmp.

Change-Id: Ib4eb711527bed297c7332c79ed6e6562a1db2cfa
Reviewed-on: https://go-review.googlesource.com/c/go/+/280444
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2020-12-26 23:03:25 -08:00
parent 2ecf52b841
commit 3bdafb0d82
6 changed files with 28 additions and 37 deletions

View file

@ -297,21 +297,18 @@ func (n *CommStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
func (n *CommStmt) copy() Node { func (n *CommStmt) copy() Node {
c := *n c := *n
c.init = c.init.Copy() c.init = c.init.Copy()
c.List = c.List.Copy()
c.Body = c.Body.Copy() c.Body = c.Body.Copy()
return &c return &c
} }
func (n *CommStmt) doChildren(do func(Node) error) error { func (n *CommStmt) doChildren(do func(Node) error) error {
var err error var err error
err = maybeDoList(n.init, err, do) err = maybeDoList(n.init, err, do)
err = maybeDoList(n.List, err, do)
err = maybeDo(n.Comm, err, do) err = maybeDo(n.Comm, err, do)
err = maybeDoList(n.Body, err, do) err = maybeDoList(n.Body, err, do)
return err return err
} }
func (n *CommStmt) editChildren(edit func(Node) Node) { func (n *CommStmt) editChildren(edit func(Node) Node) {
editList(n.init, edit) editList(n.init, edit)
editList(n.List, edit)
n.Comm = maybeEdit(n.Comm, edit) n.Comm = maybeEdit(n.Comm, edit)
editList(n.Body, edit) editList(n.Body, edit)
} }

View file

@ -220,13 +220,12 @@ func editCases(list []*CaseStmt, edit func(Node) Node) {
type CommStmt struct { type CommStmt struct {
miniStmt miniStmt
List Nodes // list of expressions for switch, early select Comm Node // communication case
Comm Node // communication case (Exprs[0]) after select is type-checked
Body Nodes Body Nodes
} }
func NewCommStmt(pos src.XPos, list, body []Node) *CommStmt { func NewCommStmt(pos src.XPos, comm Node, body []Node) *CommStmt {
n := &CommStmt{List: list, Body: body} n := &CommStmt{Comm: comm, Body: body}
n.pos = pos n.pos = pos
n.op = OCASE n.op = OCASE
return n return n
@ -274,11 +273,13 @@ type ForStmt struct {
HasBreak bool HasBreak bool
} }
func NewForStmt(pos src.XPos, init []Node, cond, post Node, body []Node) *ForStmt { func NewForStmt(pos src.XPos, init Node, cond, post Node, body []Node) *ForStmt {
n := &ForStmt{Cond: cond, Post: post} n := &ForStmt{Cond: cond, Post: post}
n.pos = pos n.pos = pos
n.op = OFOR n.op = OFOR
n.init.Set(init) if init != nil {
n.init = []Node{init}
}
n.Body.Set(body) n.Body.Set(body)
return n return n
} }

View file

@ -1149,9 +1149,11 @@ func (p *noder) blockStmt(stmt *syntax.BlockStmt) []ir.Node {
func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node { func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
p.openScope(stmt.Pos()) p.openScope(stmt.Pos())
init := p.simpleStmt(stmt.Init) init := p.stmt(stmt.Init)
n := ir.NewIfStmt(p.pos(stmt), p.expr(stmt.Cond), p.blockStmt(stmt.Then), nil) n := ir.NewIfStmt(p.pos(stmt), p.expr(stmt.Cond), p.blockStmt(stmt.Then), nil)
*n.PtrInit() = init if init != nil {
*n.PtrInit() = []ir.Node{init}
}
if stmt.Else != nil { if stmt.Else != nil {
e := p.stmt(stmt.Else) e := p.stmt(stmt.Else)
if e.Op() == ir.OBLOCK { if e.Op() == ir.OBLOCK {
@ -1186,7 +1188,7 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
return n return n
} }
n := ir.NewForStmt(p.pos(stmt), p.simpleStmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body)) n := ir.NewForStmt(p.pos(stmt), p.stmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body))
p.closeAnotherScope() p.closeAnotherScope()
return n return n
} }
@ -1194,9 +1196,11 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node { func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
p.openScope(stmt.Pos()) p.openScope(stmt.Pos())
init := p.simpleStmt(stmt.Init) init := p.stmt(stmt.Init)
n := ir.NewSwitchStmt(p.pos(stmt), p.expr(stmt.Tag), nil) n := ir.NewSwitchStmt(p.pos(stmt), p.expr(stmt.Tag), nil)
*n.PtrInit() = init if init != nil {
*n.PtrInit() = []ir.Node{init}
}
var tswitch *ir.TypeSwitchGuard var tswitch *ir.TypeSwitchGuard
if l := n.Tag; l != nil && l.Op() == ir.OTYPESW { if l := n.Tag; l != nil && l.Op() == ir.OTYPESW {
@ -1259,13 +1263,6 @@ func (p *noder) selectStmt(stmt *syntax.SelectStmt) ir.Node {
return ir.NewSelectStmt(p.pos(stmt), p.commClauses(stmt.Body, stmt.Rbrace)) return ir.NewSelectStmt(p.pos(stmt), p.commClauses(stmt.Body, stmt.Rbrace))
} }
func (p *noder) simpleStmt(stmt syntax.SimpleStmt) []ir.Node {
if stmt == nil {
return nil
}
return []ir.Node{p.stmt(stmt)}
}
func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommStmt { func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommStmt {
nodes := make([]*ir.CommStmt, len(clauses)) nodes := make([]*ir.CommStmt, len(clauses))
for i, clause := range clauses { for i, clause := range clauses {
@ -1275,7 +1272,7 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*
} }
p.openScope(clause.Pos()) p.openScope(clause.Pos())
nodes[i] = ir.NewCommStmt(p.pos(clause), p.simpleStmt(clause.Comm), p.stmts(clause.Body)) nodes[i] = ir.NewCommStmt(p.pos(clause), p.stmt(clause.Comm), p.stmts(clause.Body))
} }
if len(clauses) > 0 { if len(clauses) > 0 {
p.closeScope(rbrace) p.closeScope(rbrace)

View file

@ -1197,7 +1197,7 @@ func (w *exportWriter) commList(cases []*ir.CommStmt) {
w.uint64(uint64(len(cases))) w.uint64(uint64(len(cases)))
for _, cas := range cases { for _, cas := range cases {
w.pos(cas.Pos()) w.pos(cas.Pos())
w.stmtList(cas.List) w.node(cas.Comm)
w.stmtList(cas.Body) w.stmtList(cas.Body)
} }
} }

View file

@ -792,7 +792,7 @@ func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseStmt {
func (r *importReader) commList() []*ir.CommStmt { func (r *importReader) commList() []*ir.CommStmt {
cases := make([]*ir.CommStmt, r.uint64()) cases := make([]*ir.CommStmt, r.uint64())
for i := range cases { for i := range cases {
cases[i] = ir.NewCommStmt(r.pos(), r.stmtList(), r.stmtList()) cases[i] = ir.NewCommStmt(r.pos(), r.node(), r.stmtList())
} }
return cases return cases
} }
@ -1033,7 +1033,9 @@ func (r *importReader) node() ir.Node {
case ir.OFOR: case ir.OFOR:
pos, init := r.pos(), r.stmtList() pos, init := r.pos(), r.stmtList()
cond, post := r.exprsOrNil() cond, post := r.exprsOrNil()
return ir.NewForStmt(pos, init, cond, post, r.stmtList()) n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
n.PtrInit().Set(init)
return n
case ir.ORANGE: case ir.ORANGE:
pos := r.pos() pos := r.pos()

View file

@ -360,29 +360,23 @@ func tcReturn(n *ir.ReturnStmt) ir.Node {
// select // select
func tcSelect(sel *ir.SelectStmt) { func tcSelect(sel *ir.SelectStmt) {
var def ir.Node var def *ir.CommStmt
lno := ir.SetPos(sel) lno := ir.SetPos(sel)
Stmts(sel.Init()) Stmts(sel.Init())
for _, ncase := range sel.Cases { for _, ncase := range sel.Cases {
if len(ncase.List) == 0 { if ncase.Comm == nil {
// default // default
if def != nil { if def != nil {
base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def)) base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def))
} else { } else {
def = ncase def = ncase
} }
} else if len(ncase.List) > 1 {
base.ErrorfAt(ncase.Pos(), "select cases cannot be lists")
} else { } else {
ncase.List[0] = Stmt(ncase.List[0]) n := Stmt(ncase.Comm)
n := ncase.List[0]
ncase.Comm = n ncase.Comm = n
ncase.List.Set(nil) oselrecv2 := func(dst, recv ir.Node, def bool) {
oselrecv2 := func(dst, recv ir.Node, colas bool) { n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, nil, nil) n.Def = def
n.Lhs = []ir.Node{dst, ir.BlankNode}
n.Rhs = []ir.Node{recv}
n.Def = colas
n.SetTypecheck(1) n.SetTypecheck(1)
ncase.Comm = n ncase.Comm = n
} }