aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/stmt.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/noder/stmt.go')
-rw-r--r--src/cmd/compile/internal/noder/stmt.go32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/noder/stmt.go b/src/cmd/compile/internal/noder/stmt.go
index 32a1483b4a..fc1f5836ff 100644
--- a/src/cmd/compile/internal/noder/stmt.go
+++ b/src/cmd/compile/internal/noder/stmt.go
@@ -5,6 +5,7 @@
package noder
import (
+ "cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/syntax"
"cmd/compile/internal/typecheck"
@@ -27,6 +28,7 @@ func (g *irgen) stmts(stmts []syntax.Stmt) []ir.Node {
}
func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
+ base.Assert(g.exprStmtOK)
switch stmt := stmt.(type) {
case nil, *syntax.EmptyStmt:
return nil
@@ -35,11 +37,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
case *syntax.BlockStmt:
return ir.NewBlockStmt(g.pos(stmt), g.blockStmt(stmt))
case *syntax.ExprStmt:
- x := g.expr(stmt.X)
- if call, ok := x.(*ir.CallExpr); ok {
- call.Use = ir.CallUseStmt
- }
- return x
+ return g.expr(stmt.X)
case *syntax.SendStmt:
n := ir.NewSendStmt(g.pos(stmt), g.expr(stmt.Chan), g.expr(stmt.Value))
if n.Chan.Type().HasTParam() || n.Value.Type().HasTParam() {
@@ -52,7 +50,9 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
n.SetTypecheck(1)
return n
case *syntax.DeclStmt:
- return ir.NewBlockStmt(g.pos(stmt), g.decls(stmt.DeclList))
+ n := ir.NewBlockStmt(g.pos(stmt), nil)
+ g.decls(&n.List, stmt.DeclList)
+ return n
case *syntax.AssignStmt:
if stmt.Op != 0 && stmt.Op != syntax.Def {
@@ -61,7 +61,10 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
if stmt.Rhs == nil {
n = IncDec(g.pos(stmt), op, g.expr(stmt.Lhs))
} else {
- n = ir.NewAssignOpStmt(g.pos(stmt), op, g.expr(stmt.Lhs), g.expr(stmt.Rhs))
+ // Eval rhs before lhs, for compatibility with noder1
+ rhs := g.expr(stmt.Rhs)
+ lhs := g.expr(stmt.Lhs)
+ n = ir.NewAssignOpStmt(g.pos(stmt), op, lhs, rhs)
}
if n.X.Typecheck() == 3 {
n.SetTypecheck(3)
@@ -72,8 +75,9 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
return n
}
- names, lhs := g.assignList(stmt.Lhs, stmt.Op == syntax.Def)
+ // Eval rhs before lhs, for compatibility with noder1
rhs := g.exprList(stmt.Rhs)
+ names, lhs := g.assignList(stmt.Lhs, stmt.Op == syntax.Def)
// We must delay transforming the assign statement if any of the
// lhs or rhs nodes are also delayed, since transformAssign needs
@@ -128,6 +132,12 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
if e.Type().HasTParam() {
// Delay transforming the return statement if any of the
// return values have a type param.
+ if !ir.HasNamedResults(ir.CurFunc) {
+ transformArgs(n)
+ // But add CONVIFACE nodes where needed if
+ // any of the return values have interface type.
+ typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, true)
+ }
n.SetTypecheck(3)
return n
}
@@ -266,6 +276,12 @@ func (g *irgen) forStmt(stmt *syntax.ForStmt) ir.Node {
key, value := unpackTwo(lhs)
n := ir.NewRangeStmt(g.pos(r), key, value, g.expr(r.X), g.blockStmt(stmt.Body))
n.Def = initDefn(n, names)
+ if key != nil {
+ transformCheckAssign(n, key)
+ }
+ if value != nil {
+ transformCheckAssign(n, value)
+ }
return n
}