зеркало из https://github.com/CryptoPro/go.git
[dev.regabi] cmd/compile: cleanup for concrete types - noder
An automated rewrite will add concrete type assertions after a test of n.Op(), when n can be safely type-asserted (meaning, n is not reassigned a different type, n is not reassigned and then used outside the scope of the type assertion, and so on). This sequence of CLs handles the code that the automated rewrite does not: adding specific types to function arguments, adjusting code not to call n.Left() etc when n may have multiple representations, and so on. This CL focuses on noder.go. Passes buildall w/ toolstash -cmp. Change-Id: Ie870126b51558e83c738add8e91a2804ed6d7f92 Reviewed-on: https://go-review.googlesource.com/c/go/+/277931 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Родитель
5024396563
Коммит
be64c8bece
|
@ -527,13 +527,13 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
|
||||||
if fun.Recv == nil {
|
if fun.Recv == nil {
|
||||||
if name.Name == "init" {
|
if name.Name == "init" {
|
||||||
name = renameinit()
|
name = renameinit()
|
||||||
if t.List().Len() > 0 || t.Rlist().Len() > 0 {
|
if len(t.Params) > 0 || len(t.Results) > 0 {
|
||||||
base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
|
base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.LocalPkg.Name == "main" && name.Name == "main" {
|
if types.LocalPkg.Name == "main" && name.Name == "main" {
|
||||||
if t.List().Len() > 0 || t.Rlist().Len() > 0 {
|
if len(t.Params) > 0 || len(t.Results) > 0 {
|
||||||
base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
|
base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,10 +983,10 @@ func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []ir.Node {
|
||||||
for i, stmt := range stmts {
|
for i, stmt := range stmts {
|
||||||
s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
|
s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
|
||||||
if s == nil {
|
if s == nil {
|
||||||
} else if s.Op() == ir.OBLOCK && s.List().Len() > 0 {
|
} else if s.Op() == ir.OBLOCK && s.(*ir.BlockStmt).List().Len() > 0 {
|
||||||
// Inline non-empty block.
|
// Inline non-empty block.
|
||||||
// Empty blocks must be preserved for checkreturn.
|
// Empty blocks must be preserved for checkreturn.
|
||||||
nodes = append(nodes, s.List().Slice()...)
|
nodes = append(nodes, s.(*ir.BlockStmt).List().Slice()...)
|
||||||
} else {
|
} else {
|
||||||
nodes = append(nodes, s)
|
nodes = append(nodes, s)
|
||||||
}
|
}
|
||||||
|
@ -1020,22 +1020,23 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
|
||||||
return liststmt(p.decls(stmt.DeclList))
|
return liststmt(p.decls(stmt.DeclList))
|
||||||
case *syntax.AssignStmt:
|
case *syntax.AssignStmt:
|
||||||
if stmt.Op != 0 && stmt.Op != syntax.Def {
|
if stmt.Op != 0 && stmt.Op != syntax.Def {
|
||||||
n := p.nod(stmt, ir.OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
|
n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs))
|
||||||
n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
|
n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
|
||||||
n.SetSubOp(p.binOp(stmt.Op))
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
rhs := p.exprList(stmt.Rhs)
|
rhs := p.exprList(stmt.Rhs)
|
||||||
if list, ok := stmt.Lhs.(*syntax.ListExpr); ok && len(list.ElemList) != 1 || len(rhs) != 1 {
|
if list, ok := stmt.Lhs.(*syntax.ListExpr); ok && len(list.ElemList) != 1 || len(rhs) != 1 {
|
||||||
n := p.nod(stmt, ir.OAS2, nil, nil)
|
n := p.nod(stmt, ir.OAS2, nil, nil)
|
||||||
n.PtrList().Set(p.assignList(stmt.Lhs, n, stmt.Op == syntax.Def))
|
n.SetColas(stmt.Op == syntax.Def)
|
||||||
|
n.PtrList().Set(p.assignList(stmt.Lhs, n, n.Colas()))
|
||||||
n.PtrRlist().Set(rhs)
|
n.PtrRlist().Set(rhs)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
n := p.nod(stmt, ir.OAS, nil, nil)
|
n := p.nod(stmt, ir.OAS, nil, nil)
|
||||||
n.SetLeft(p.assignList(stmt.Lhs, n, stmt.Op == syntax.Def)[0])
|
n.SetColas(stmt.Op == syntax.Def)
|
||||||
|
n.SetLeft(p.assignList(stmt.Lhs, n, n.Colas())[0])
|
||||||
n.SetRight(rhs[0])
|
n.SetRight(rhs[0])
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
@ -1110,8 +1111,6 @@ func (p *noder) assignList(expr syntax.Expr, defn ir.Node, colas bool) []ir.Node
|
||||||
return p.exprList(expr)
|
return p.exprList(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
defn.SetColas(true)
|
|
||||||
|
|
||||||
var exprs []syntax.Expr
|
var exprs []syntax.Expr
|
||||||
if list, ok := expr.(*syntax.ListExpr); ok {
|
if list, ok := expr.(*syntax.ListExpr); ok {
|
||||||
exprs = list.ElemList
|
exprs = list.ElemList
|
||||||
|
@ -1196,27 +1195,30 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
|
||||||
|
|
||||||
func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
|
func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
|
||||||
p.openScope(stmt.Pos())
|
p.openScope(stmt.Pos())
|
||||||
var n ir.Node
|
|
||||||
if r, ok := stmt.Init.(*syntax.RangeClause); ok {
|
if r, ok := stmt.Init.(*syntax.RangeClause); ok {
|
||||||
if stmt.Cond != nil || stmt.Post != nil {
|
if stmt.Cond != nil || stmt.Post != nil {
|
||||||
panic("unexpected RangeClause")
|
panic("unexpected RangeClause")
|
||||||
}
|
}
|
||||||
|
|
||||||
n = p.nod(r, ir.ORANGE, nil, p.expr(r.X))
|
n := p.nod(r, ir.ORANGE, nil, p.expr(r.X))
|
||||||
if r.Lhs != nil {
|
if r.Lhs != nil {
|
||||||
n.PtrList().Set(p.assignList(r.Lhs, n, r.Def))
|
n.SetColas(r.Def)
|
||||||
}
|
n.PtrList().Set(p.assignList(r.Lhs, n, n.Colas()))
|
||||||
} else {
|
|
||||||
n = p.nod(stmt, ir.OFOR, nil, nil)
|
|
||||||
if stmt.Init != nil {
|
|
||||||
n.PtrInit().Set1(p.stmt(stmt.Init))
|
|
||||||
}
|
|
||||||
if stmt.Cond != nil {
|
|
||||||
n.SetLeft(p.expr(stmt.Cond))
|
|
||||||
}
|
|
||||||
if stmt.Post != nil {
|
|
||||||
n.SetRight(p.stmt(stmt.Post))
|
|
||||||
}
|
}
|
||||||
|
n.PtrBody().Set(p.blockStmt(stmt.Body))
|
||||||
|
p.closeAnotherScope()
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
n := p.nod(stmt, ir.OFOR, nil, nil)
|
||||||
|
if stmt.Init != nil {
|
||||||
|
n.PtrInit().Set1(p.stmt(stmt.Init))
|
||||||
|
}
|
||||||
|
if stmt.Cond != nil {
|
||||||
|
n.SetLeft(p.expr(stmt.Cond))
|
||||||
|
}
|
||||||
|
if stmt.Post != nil {
|
||||||
|
n.SetRight(p.stmt(stmt.Post))
|
||||||
}
|
}
|
||||||
n.PtrBody().Set(p.blockStmt(stmt.Body))
|
n.PtrBody().Set(p.blockStmt(stmt.Body))
|
||||||
p.closeAnotherScope()
|
p.closeAnotherScope()
|
||||||
|
@ -1233,9 +1235,9 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
|
||||||
n.SetLeft(p.expr(stmt.Tag))
|
n.SetLeft(p.expr(stmt.Tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
tswitch := n.Left()
|
var tswitch *ir.TypeSwitchGuard
|
||||||
if tswitch != nil && tswitch.Op() != ir.OTYPESW {
|
if l := n.Left(); l != nil && l.Op() == ir.OTYPESW {
|
||||||
tswitch = nil
|
tswitch = l.(*ir.TypeSwitchGuard)
|
||||||
}
|
}
|
||||||
n.PtrList().Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace))
|
n.PtrList().Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace))
|
||||||
|
|
||||||
|
@ -1243,7 +1245,7 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch ir.Node, rbrace syntax.Pos) []ir.Node {
|
func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.TypeSwitchGuard, rbrace syntax.Pos) []ir.Node {
|
||||||
nodes := make([]ir.Node, 0, len(clauses))
|
nodes := make([]ir.Node, 0, len(clauses))
|
||||||
for i, clause := range clauses {
|
for i, clause := range clauses {
|
||||||
p.setlineno(clause)
|
p.setlineno(clause)
|
||||||
|
@ -1328,10 +1330,18 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
|
||||||
var ls ir.Node
|
var ls ir.Node
|
||||||
if label.Stmt != nil { // TODO(mdempsky): Should always be present.
|
if label.Stmt != nil { // TODO(mdempsky): Should always be present.
|
||||||
ls = p.stmtFall(label.Stmt, fallOK)
|
ls = p.stmtFall(label.Stmt, fallOK)
|
||||||
switch label.Stmt.(type) {
|
// Attach label directly to control statement too.
|
||||||
case *syntax.ForStmt, *syntax.SwitchStmt, *syntax.SelectStmt:
|
if ls != nil {
|
||||||
// Attach label directly to control statement too.
|
switch ls.Op() {
|
||||||
ls.SetSym(sym)
|
case ir.OFOR:
|
||||||
|
ls.SetSym(sym)
|
||||||
|
case ir.ORANGE:
|
||||||
|
ls.SetSym(sym)
|
||||||
|
case ir.OSWITCH:
|
||||||
|
ls.SetSym(sym)
|
||||||
|
case ir.OSELECT:
|
||||||
|
ls.SetSym(sym)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1483,8 +1493,9 @@ func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case ir.ONAME, ir.ONONAME, ir.OPACK:
|
case ir.ONAME, ir.ONONAME, ir.OPACK:
|
||||||
x = p.nod(n, ir.OPAREN, x, nil)
|
p := p.nod(n, ir.OPAREN, x, nil)
|
||||||
x.SetImplicit(true)
|
p.SetImplicit(true)
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// errorcheck
|
||||||
|
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main(int) {} // ERROR "func main must have no arguments and no return values"
|
||||||
|
func main() int { return 1 } // ERROR "func main must have no arguments and no return values" "main redeclared in this block"
|
||||||
|
|
||||||
|
func init(int) {} // ERROR "func init must have no arguments and no return values"
|
||||||
|
func init() int { return 1 } // ERROR "func init must have no arguments and no return values"
|
Загрузка…
Ссылка в новой задаче