]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
authorRuss Cox <rsc@golang.org>
Wed, 23 Dec 2020 04:56:32 +0000 (23:56 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 23 Dec 2020 06:37:34 +0000 (06:37 +0000)
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.

Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.

There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.

Passes buildall w/ toolstash -cmp.

[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
        import "cmd/compile/internal/ir"
        var n ir.Node

        n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
        n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
        n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
        n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
        n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
        n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
        n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
        n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
        n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
        n.Op() == ir.OAS -> n.(*ir.AssignStmt)
        n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
        n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
        n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
        n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
        n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
        n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
        n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
        n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
        n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
        n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
        n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
        n.Op() == ir.OCALL -> n.(*ir.CallExpr)
        n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
        n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
        n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
        n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
        n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
        n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
        n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
        n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
        n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
        n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
        n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
        n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
        n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
        n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
        n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
        n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
        n.Op() == ir.ODCL -> n.(*ir.Decl)
        n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
        n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
        n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
        n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
        n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
        n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
        n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
        n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
        n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
        n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
        n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
        n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
        n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
        n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
        n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
        n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
        n.Op() == ir.OFOR -> n.(*ir.ForStmt)
        n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
        n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
        n.Op() == ir.OGETG -> n.(*ir.CallExpr)
        n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
        n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
        n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
        n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
        n.Op() == ir.OIF -> n.(*ir.IfStmt)
        n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
        n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
        n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
        n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
        n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
        n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
        n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
        n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
        n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
        n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
        n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
        n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
        n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
        n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
        n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
        n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
        n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
        n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
        n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
        n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
        n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
        n.Op() == ir.ONAME -> n.(*ir.Name)
        n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
        n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
        n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
        n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
        n.Op() == ir.ONIL -> n.(*ir.NilExpr)
        n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
        n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
        n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
        n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
        n.Op() == ir.OPACK -> n.(*ir.PkgName)
        n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
        n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
        n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
        n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
        n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
        n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
        n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
        n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
        n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
        n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
        n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
        n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
        n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
        n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
        n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
        n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
        n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
        n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
        n.Op() == ir.OSEND -> n.(*ir.SendStmt)
        n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
        n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
        n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
        n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
        n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
        n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
        n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
        n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
        n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
        n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
        n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
        n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
        n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
        n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
        n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
        n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
        n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
        n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
        n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
        n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
        n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'

cd ../ir
rf '
        rm \
                Node.SetOp \
                miniNode.SetOp \
                Node.Func \
                miniNode.Func \
                Node.Left Node.SetLeft \
                miniNode.Left miniNode.SetLeft \
                Node.Right Node.SetRight \
                miniNode.Right miniNode.SetRight \
                Node.List Node.PtrList Node.SetList \
                miniNode.List miniNode.PtrList miniNode.SetList \
                Node.Rlist Node.PtrRlist Node.SetRlist \
                miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
                Node.Body Node.PtrBody Node.SetBody \
                miniNode.Body miniNode.PtrBody miniNode.SetBody \
                Node.SubOp Node.SetSubOp \
                miniNode.SubOp miniNode.SetSubOp \
                Node.SetSym \
                miniNode.SetSym \
                Node.Offset Node.SetOffset \
                miniNode.Offset miniNode.SetOffset \
                Node.Class Node.SetClass \
                miniNode.Class miniNode.SetClass \
                Node.Iota Node.SetIota \
                miniNode.Iota miniNode.SetIota \
                Node.Colas Node.SetColas \
                miniNode.Colas miniNode.SetColas \
                Node.Transient Node.SetTransient \
                miniNode.Transient miniNode.SetTransient \
                Node.Implicit Node.SetImplicit \
                miniNode.Implicit miniNode.SetImplicit \
                Node.IsDDD Node.SetIsDDD \
                miniNode.IsDDD miniNode.SetIsDDD \
                Node.MarkReadonly \
                miniNode.MarkReadonly \
                Node.Likely Node.SetLikely \
                miniNode.Likely miniNode.SetLikely \
                Node.SliceBounds Node.SetSliceBounds \
                miniNode.SliceBounds miniNode.SetSliceBounds \
                Node.NoInline Node.SetNoInline \
                miniNode.NoInline miniNode.SetNoInline \
                Node.IndexMapLValue Node.SetIndexMapLValue \
                miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
                Node.ResetAux \
                miniNode.ResetAux \
                Node.HasBreak Node.SetHasBreak \
                miniNode.HasBreak miniNode.SetHasBreak \
                Node.Bounded Node.SetBounded \
                miniNode.Bounded miniNode.SetBounded \
                miniNode.Embedded miniNode.SetEmbedded \
                miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
                miniNode.BoolVal miniNode.StringVal \
                miniNode.TChanDir miniNode.SetTChanDir \
                miniNode.Format \
                miniNode.copy miniNode.doChildren miniNode.editChildren \

'

Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
19 files changed:
src/cmd/compile/internal/gc/const.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/iexport.go
src/cmd/compile/internal/gc/iimport.go
src/cmd/compile/internal/gc/initorder.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/gc/order.go
src/cmd/compile/internal/gc/scc.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/swt.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/unsafe.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ir/mini.go
src/cmd/compile/internal/ir/node.go

index f8e60ea0a325009b7de52d4de65eeea899cad9d4..e54cd0a1028bb162f5f9182bd91c091e69987f37 100644 (file)
@@ -204,6 +204,7 @@ func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir
                return n
 
        case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+               n := n.(*ir.BinaryExpr)
                if !t.IsBoolean() {
                        break
                }
@@ -211,6 +212,7 @@ func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir
                return n
 
        case ir.OLSH, ir.ORSH:
+               n := n.(*ir.BinaryExpr)
                n.SetLeft(convlit1(n.Left(), t, explicit, nil))
                n.SetType(n.Left().Type())
                if n.Type() != nil && !n.Type().IsInteger() {
@@ -449,6 +451,7 @@ func evalConst(n ir.Node) ir.Node {
        // Pick off just the opcodes that can be constant evaluated.
        switch n.Op() {
        case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
+               n := n.(*ir.UnaryExpr)
                nl := n.Left()
                if nl.Op() == ir.OLITERAL {
                        var prec uint
@@ -459,6 +462,7 @@ func evalConst(n ir.Node) ir.Node {
                }
 
        case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT:
+               n := n.(*ir.BinaryExpr)
                nl, nr := n.Left(), n.Right()
                if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
                        rval := nr.Val()
@@ -483,18 +487,21 @@ func evalConst(n ir.Node) ir.Node {
                }
 
        case ir.OOROR, ir.OANDAND:
+               n := n.(*ir.LogicalExpr)
                nl, nr := n.Left(), n.Right()
                if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
                        return origConst(n, constant.BinaryOp(nl.Val(), tokenForOp[n.Op()], nr.Val()))
                }
 
        case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+               n := n.(*ir.BinaryExpr)
                nl, nr := n.Left(), n.Right()
                if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
                        return origBoolConst(n, constant.Compare(nl.Val(), tokenForOp[n.Op()], nr.Val()))
                }
 
        case ir.OLSH, ir.ORSH:
+               n := n.(*ir.BinaryExpr)
                nl, nr := n.Left(), n.Right()
                if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
                        // shiftBound from go/types; "so we can express smallestFloat64"
@@ -509,12 +516,14 @@ func evalConst(n ir.Node) ir.Node {
                }
 
        case ir.OCONV, ir.ORUNESTR:
+               n := n.(*ir.ConvExpr)
                nl := n.Left()
                if ir.OKForConst[n.Type().Kind()] && nl.Op() == ir.OLITERAL {
                        return origConst(n, convertVal(nl.Val(), n.Type(), true))
                }
 
        case ir.OCONVNOP:
+               n := n.(*ir.ConvExpr)
                nl := n.Left()
                if ir.OKForConst[n.Type().Kind()] && nl.Op() == ir.OLITERAL {
                        // set so n.Orig gets OCONV instead of OCONVNOP
@@ -524,6 +533,7 @@ func evalConst(n ir.Node) ir.Node {
 
        case ir.OADDSTR:
                // Merge adjacent constants in the argument list.
+               n := n.(*ir.AddStringExpr)
                s := n.List().Slice()
                need := 0
                for i := 0; i < len(s); i++ {
@@ -567,6 +577,7 @@ func evalConst(n ir.Node) ir.Node {
                return nn
 
        case ir.OCAP, ir.OLEN:
+               n := n.(*ir.UnaryExpr)
                nl := n.Left()
                switch nl.Type().Kind() {
                case types.TSTRING:
@@ -580,21 +591,25 @@ func evalConst(n ir.Node) ir.Node {
                }
 
        case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+               n := n.(*ir.UnaryExpr)
                return origIntConst(n, evalunsafe(n))
 
        case ir.OREAL:
+               n := n.(*ir.UnaryExpr)
                nl := n.Left()
                if nl.Op() == ir.OLITERAL {
                        return origConst(n, constant.Real(nl.Val()))
                }
 
        case ir.OIMAG:
+               n := n.(*ir.UnaryExpr)
                nl := n.Left()
                if nl.Op() == ir.OLITERAL {
                        return origConst(n, constant.Imag(nl.Val()))
                }
 
        case ir.OCOMPLEX:
+               n := n.(*ir.BinaryExpr)
                nl, nr := n.Left(), n.Right()
                if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
                        return origConst(n, makeComplex(nl.Val(), nr.Val()))
@@ -854,6 +869,7 @@ type constSetKey struct {
 // n must not be an untyped constant.
 func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) {
        if conv := n; conv.Op() == ir.OCONVIFACE {
+               conv := conv.(*ir.ConvExpr)
                if conv.Implicit() {
                        n = conv.Left()
                }
index 3cfb24f2fc4b8773bd9308ac9f7cce37b5cc990e..d85f10faf3c439e2daed6eafa53461b87447bbfb 100644 (file)
@@ -229,6 +229,7 @@ func oldname(s *types.Sym) ir.Node {
                // are parsing x := 5 inside the closure, until we get to
                // the := it looks like a reference to the outer x so we'll
                // make x a closure variable unnecessarily.
+               n := n.(*ir.Name)
                c := n.Name().Innermost
                if c == nil || c.Curfn != Curfn {
                        // Do not have a closure var for the active closure yet; make one.
@@ -890,6 +891,7 @@ func (c *nowritebarrierrecChecker) findExtraCalls(nn ir.Node) {
        arg := n.List().First()
        switch arg.Op() {
        case ir.ONAME:
+               arg := arg.(*ir.Name)
                callee = arg.Name().Defn.(*ir.Func)
        case ir.OCLOSURE:
                arg := arg.(*ir.ClosureExpr)
index c03445044df424bec80ac8767d1d6dcc90e24da7..0f7d62c5bfe39783957418b97faa7d648270c734 100644 (file)
@@ -1067,11 +1067,13 @@ func (w *exportWriter) stmt(n ir.Node) {
                // (At the moment neither the parser nor the typechecker
                // generate OBLOCK nodes except to denote an empty
                // function body, although that may change.)
+               n := n.(*ir.BlockStmt)
                for _, n := range n.List().Slice() {
                        w.stmt(n)
                }
 
        case ir.ODCL:
+               n := n.(*ir.Decl)
                w.op(ir.ODCL)
                w.pos(n.Left().Pos())
                w.localName(n.Left().(*ir.Name))
@@ -1081,6 +1083,7 @@ func (w *exportWriter) stmt(n ir.Node) {
                // Don't export "v = <N>" initializing statements, hope they're always
                // preceded by the DCL which will be re-parsed and typecheck to reproduce
                // the "v = <N>" again.
+               n := n.(*ir.AssignStmt)
                if n.Right() != nil {
                        w.op(ir.OAS)
                        w.pos(n.Pos())
@@ -1099,12 +1102,14 @@ func (w *exportWriter) stmt(n ir.Node) {
                }
 
        case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+               n := n.(*ir.AssignListStmt)
                w.op(ir.OAS2)
                w.pos(n.Pos())
                w.exprList(n.List())
                w.exprList(n.Rlist())
 
        case ir.ORETURN:
+               n := n.(*ir.ReturnStmt)
                w.op(ir.ORETURN)
                w.pos(n.Pos())
                w.exprList(n.List())
@@ -1113,11 +1118,13 @@ func (w *exportWriter) stmt(n ir.Node) {
        //      unreachable - generated by compiler for trampolin routines
 
        case ir.OGO, ir.ODEFER:
+               n := n.(*ir.GoDeferStmt)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                w.op(ir.OIF)
                w.pos(n.Pos())
                w.stmtList(n.Init())
@@ -1126,6 +1133,7 @@ func (w *exportWriter) stmt(n ir.Node) {
                w.stmtList(n.Rlist())
 
        case ir.OFOR:
+               n := n.(*ir.ForStmt)
                w.op(ir.OFOR)
                w.pos(n.Pos())
                w.stmtList(n.Init())
@@ -1133,6 +1141,7 @@ func (w *exportWriter) stmt(n ir.Node) {
                w.stmtList(n.Body())
 
        case ir.ORANGE:
+               n := n.(*ir.RangeStmt)
                w.op(ir.ORANGE)
                w.pos(n.Pos())
                w.stmtList(n.List())
@@ -1140,6 +1149,7 @@ func (w *exportWriter) stmt(n ir.Node) {
                w.stmtList(n.Body())
 
        case ir.OSELECT:
+               n := n.(*ir.SelectStmt)
                w.op(n.Op())
                w.pos(n.Pos())
                w.stmtList(n.Init())
@@ -1147,6 +1157,7 @@ func (w *exportWriter) stmt(n ir.Node) {
                w.caseList(n)
 
        case ir.OSWITCH:
+               n := n.(*ir.SwitchStmt)
                w.op(n.Op())
                w.pos(n.Pos())
                w.stmtList(n.Init())
@@ -1157,6 +1168,7 @@ func (w *exportWriter) stmt(n ir.Node) {
        //      handled by caseList
 
        case ir.OFALL:
+               n := n.(*ir.BranchStmt)
                w.op(ir.OFALL)
                w.pos(n.Pos())
 
@@ -1217,16 +1229,20 @@ func (w *exportWriter) exprList(list ir.Nodes) {
 func simplifyForExport(n ir.Node) ir.Node {
        switch n.Op() {
        case ir.OPAREN:
+               n := n.(*ir.ParenExpr)
                return simplifyForExport(n.Left())
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                if n.Implicit() {
                        return simplifyForExport(n.Left())
                }
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                if n.Implicit() {
                        return simplifyForExport(n.Left())
                }
        case ir.ODOT, ir.ODOTPTR:
+               n := n.(*ir.SelectorExpr)
                if n.Implicit() {
                        return simplifyForExport(n.Left())
                }
@@ -1240,6 +1256,7 @@ func (w *exportWriter) expr(n ir.Node) {
        // expressions
        // (somewhat closely following the structure of exprfmt in fmt.go)
        case ir.ONIL:
+               n := n.(*ir.NilExpr)
                if !n.Type().HasNil() {
                        base.Fatalf("unexpected type for nil: %v", n.Type())
                }
@@ -1284,6 +1301,7 @@ func (w *exportWriter) expr(n ir.Node) {
                w.typ(n.Type())
 
        case ir.OTYPESW:
+               n := n.(*ir.TypeSwitchGuard)
                w.op(ir.OTYPESW)
                w.pos(n.Pos())
                var s *types.Sym
@@ -1306,23 +1324,27 @@ func (w *exportWriter) expr(n ir.Node) {
        //      should have been resolved by typechecking - handled by default case
 
        case ir.OPTRLIT:
+               n := n.(*ir.AddrExpr)
                w.op(ir.OADDR)
                w.pos(n.Pos())
                w.expr(n.Left())
 
        case ir.OSTRUCTLIT:
+               n := n.(*ir.CompLitExpr)
                w.op(ir.OSTRUCTLIT)
                w.pos(n.Pos())
                w.typ(n.Type())
                w.fieldList(n.List()) // special handling of field names
 
        case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+               n := n.(*ir.CompLitExpr)
                w.op(ir.OCOMPLIT)
                w.pos(n.Pos())
                w.typ(n.Type())
                w.exprList(n.List())
 
        case ir.OKEY:
+               n := n.(*ir.KeyExpr)
                w.op(ir.OKEY)
                w.pos(n.Pos())
                w.exprsOrNil(n.Left(), n.Right())
@@ -1332,30 +1354,35 @@ func (w *exportWriter) expr(n ir.Node) {
 
        case ir.OCALLPART:
                // An OCALLPART is an OXDOT before type checking.
+               n := n.(*ir.CallPartExpr)
                w.op(ir.OXDOT)
                w.pos(n.Pos())
                w.expr(n.Left())
                w.selector(n.Sym())
 
        case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
+               n := n.(*ir.SelectorExpr)
                w.op(ir.OXDOT)
                w.pos(n.Pos())
                w.expr(n.Left())
                w.selector(n.Sym())
 
        case ir.ODOTTYPE, ir.ODOTTYPE2:
+               n := n.(*ir.TypeAssertExpr)
                w.op(ir.ODOTTYPE)
                w.pos(n.Pos())
                w.expr(n.Left())
                w.typ(n.Type())
 
        case ir.OINDEX, ir.OINDEXMAP:
+               n := n.(*ir.IndexExpr)
                w.op(ir.OINDEX)
                w.pos(n.Pos())
                w.expr(n.Left())
                w.expr(n.Right())
 
        case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
+               n := n.(*ir.SliceExpr)
                w.op(ir.OSLICE)
                w.pos(n.Pos())
                w.expr(n.Left())
@@ -1363,6 +1390,7 @@ func (w *exportWriter) expr(n ir.Node) {
                w.exprsOrNil(low, high)
 
        case ir.OSLICE3, ir.OSLICE3ARR:
+               n := n.(*ir.SliceExpr)
                w.op(ir.OSLICE3)
                w.pos(n.Pos())
                w.expr(n.Left())
@@ -1372,6 +1400,7 @@ func (w *exportWriter) expr(n ir.Node) {
 
        case ir.OCOPY, ir.OCOMPLEX:
                // treated like other builtin calls (see e.g., OREAL)
+               n := n.(*ir.BinaryExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
@@ -1379,18 +1408,21 @@ func (w *exportWriter) expr(n ir.Node) {
                w.op(ir.OEND)
 
        case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR:
+               n := n.(*ir.ConvExpr)
                w.op(ir.OCONV)
                w.pos(n.Pos())
                w.expr(n.Left())
                w.typ(n.Type())
 
        case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
+               n := n.(*ir.UnaryExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
                w.op(ir.OEND)
 
        case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
+               n := n.(*ir.CallExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.exprList(n.List()) // emits terminating OEND
@@ -1402,6 +1434,7 @@ func (w *exportWriter) expr(n ir.Node) {
                }
 
        case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
+               n := n.(*ir.CallExpr)
                w.op(ir.OCALL)
                w.pos(n.Pos())
                w.stmtList(n.Init())
@@ -1410,6 +1443,7 @@ func (w *exportWriter) expr(n ir.Node) {
                w.bool(n.IsDDD())
 
        case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
+               n := n.(*ir.MakeExpr)
                w.op(n.Op()) // must keep separate from OMAKE for importer
                w.pos(n.Pos())
                w.typ(n.Type())
@@ -1428,21 +1462,25 @@ func (w *exportWriter) expr(n ir.Node) {
 
        // unary expressions
        case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
+               n := n.(*ir.UnaryExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
 
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
 
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
 
        case ir.OSEND:
+               n := n.(*ir.SendStmt)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
@@ -1451,18 +1489,21 @@ func (w *exportWriter) expr(n ir.Node) {
        // binary expressions
        case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
                ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
+               n := n.(*ir.BinaryExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
                w.expr(n.Right())
 
        case ir.OANDAND, ir.OOROR:
+               n := n.(*ir.LogicalExpr)
                w.op(n.Op())
                w.pos(n.Pos())
                w.expr(n.Left())
                w.expr(n.Right())
 
        case ir.OADDSTR:
+               n := n.(*ir.AddStringExpr)
                w.op(ir.OADDSTR)
                w.pos(n.Pos())
                w.exprList(n.List())
index 1148d329a3cb2efb6263f280095bb96a01e9c54d..40f76cae7bb60b6a2ecb8742ad054ec04bd81022 100644 (file)
@@ -756,6 +756,7 @@ func (r *importReader) stmtList() []ir.Node {
                // but the handling of ODCL calls liststmt, which creates one.
                // Inline them into the statement list.
                if n.Op() == ir.OBLOCK {
+                       n := n.(*ir.BlockStmt)
                        list = append(list, n.List().Slice()...)
                } else {
                        list = append(list, n)
@@ -802,6 +803,7 @@ func (r *importReader) exprList() []ir.Node {
 func (r *importReader) expr() ir.Node {
        n := r.node()
        if n != nil && n.Op() == ir.OBLOCK {
+               n := n.(*ir.BlockStmt)
                base.Fatalf("unexpected block node: %v", n)
        }
        return n
index c9c3361d3cf8197db30046d3b2e3cb0bc933995b..f99c6dd72c99126bcac0f4598ef876126f757eb2 100644 (file)
@@ -254,10 +254,13 @@ func collectDeps(n ir.Node, transitive bool) ir.NameSet {
        d := initDeps{transitive: transitive}
        switch n.Op() {
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                d.inspect(n.Right())
        case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+               n := n.(*ir.AssignListStmt)
                d.inspect(n.Rlist().First())
        case ir.ODCLFUNC:
+               n := n.(*ir.Func)
                d.inspectList(n.Body())
        default:
                base.Fatalf("unexpected Op: %v", n.Op())
@@ -286,6 +289,7 @@ func (d *initDeps) inspectList(l ir.Nodes) { ir.VisitList(l, d.cachedVisit()) }
 func (d *initDeps) visit(n ir.Node) {
        switch n.Op() {
        case ir.OMETHEXPR:
+               n := n.(*ir.MethodExpr)
                d.foundDep(methodExprName(n))
 
        case ir.ONAME:
@@ -355,8 +359,10 @@ func (s *declOrder) Pop() interface{} {
 func firstLHS(n ir.Node) *ir.Name {
        switch n.Op() {
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                return n.Left().Name()
        case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR:
+               n := n.(*ir.AssignListStmt)
                return n.List().First().Name()
        }
 
index 122c19f6df18ed51ed1de9ea0447628ba8b50250..7cb79468065a9b10f1d31a7a76e001d0c65ef276 100644 (file)
@@ -377,6 +377,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
 
        // Call is okay if inlinable and we have the budget for the body.
        case ir.OCALLMETH:
+               n := n.(*ir.CallExpr)
                t := n.Left().Type()
                if t == nil {
                        base.Fatalf("no function type for [%p] %+v\n", n.Left(), n.Left())
@@ -429,22 +430,26 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
                return nil
 
        case ir.OFOR, ir.OFORUNTIL:
+               n := n.(*ir.ForStmt)
                if n.Sym() != nil {
                        return errors.New("labeled control")
                }
        case ir.OSWITCH:
+               n := n.(*ir.SwitchStmt)
                if n.Sym() != nil {
                        return errors.New("labeled control")
                }
        // case ir.ORANGE, ir.OSELECT in "unhandled" above
 
        case ir.OBREAK, ir.OCONTINUE:
+               n := n.(*ir.BranchStmt)
                if n.Sym() != nil {
                        // Should have short-circuited due to labeled control error above.
                        base.Fatalf("unexpected labeled break/continue: %v", n)
                }
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                if ir.IsConst(n.Left(), constant.Bool) {
                        // This if and the condition cost nothing.
                        // TODO(rsc): It seems strange that we visit the dead branch.
@@ -569,8 +574,10 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
 
        switch n.Op() {
        case ir.ODEFER, ir.OGO:
+               n := n.(*ir.GoDeferStmt)
                switch call := n.Left(); call.Op() {
                case ir.OCALLFUNC, ir.OCALLMETH:
+                       call := call.(*ir.CallExpr)
                        call.SetNoInline(true)
                }
 
@@ -581,6 +588,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
        case ir.OCALLMETH:
                // Prevent inlining some reflect.Value methods when using checkptr,
                // even when package reflect was compiled without it (#35073).
+               n := n.(*ir.CallExpr)
                if s := n.Left().Sym(); base.Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
                        return n
                }
@@ -591,6 +599,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
        ir.EditChildren(n, edit)
 
        if as := n; as.Op() == ir.OAS2FUNC {
+               as := as.(*ir.AssignListStmt)
                if as.Rlist().First().Op() == ir.OINLCALL {
                        as.PtrRlist().Set(inlconv2list(as.Rlist().First().(*ir.InlinedCallExpr)))
                        as.SetOp(ir.OAS2)
@@ -604,6 +613,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
        // switch at the top of this function.
        switch n.Op() {
        case ir.OCALLFUNC, ir.OCALLMETH:
+               n := n.(*ir.CallExpr)
                if n.NoInline() {
                        return n
                }
@@ -673,6 +683,7 @@ func inlCallee(fn ir.Node) *ir.Func {
                }
                return n.Func()
        case ir.ONAME:
+               fn := fn.(*ir.Name)
                if fn.Class() == ir.PFUNC {
                        return fn.Func()
                }
@@ -721,8 +732,10 @@ func staticValue1(nn ir.Node) ir.Node {
 FindRHS:
        switch defn.Op() {
        case ir.OAS:
+               defn := defn.(*ir.AssignStmt)
                rhs = defn.Right()
        case ir.OAS2:
+               defn := defn.(*ir.AssignListStmt)
                for i, lhs := range defn.List().Slice() {
                        if lhs == n {
                                rhs = defn.Rlist().Index(i)
@@ -761,10 +774,12 @@ func reassigned(name *ir.Name) bool {
        return ir.Any(name.Curfn, func(n ir.Node) bool {
                switch n.Op() {
                case ir.OAS:
+                       n := n.(*ir.AssignStmt)
                        if n.Left() == name && n != name.Defn {
                                return true
                        }
                case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OSELRECV2:
+                       n := n.(*ir.AssignListStmt)
                        for _, p := range n.List().Slice() {
                                if p == name && n != name.Defn {
                                        return true
@@ -1237,6 +1252,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
                return n
 
        case ir.OMETHEXPR:
+               n := n.(*ir.MethodExpr)
                return n
 
        case ir.OLITERAL, ir.ONIL, ir.OTYPE:
@@ -1259,6 +1275,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
        case ir.ORETURN:
                // Since we don't handle bodies with closures,
                // this return is guaranteed to belong to the current inlined function.
+               n := n.(*ir.ReturnStmt)
                init := subst.list(n.Init())
                if len(subst.retvars) != 0 && n.List().Len() != 0 {
                        as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
@@ -1285,6 +1302,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
                return ir.NewBlockStmt(base.Pos, init)
 
        case ir.OGOTO:
+               n := n.(*ir.BranchStmt)
                m := ir.Copy(n).(*ir.BranchStmt)
                m.SetPos(subst.updatedPos(m.Pos()))
                m.PtrInit().Set(nil)
@@ -1293,6 +1311,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
                return m
 
        case ir.OLABEL:
+               n := n.(*ir.LabelStmt)
                m := ir.Copy(n).(*ir.LabelStmt)
                m.SetPos(subst.updatedPos(m.Pos()))
                m.PtrInit().Set(nil)
@@ -1365,6 +1384,7 @@ func devirtualizeCall(call *ir.CallExpr) {
        x := typecheck(ir.NewSelectorExpr(sel.Pos(), ir.OXDOT, dt, sel.Sym()), ctxExpr|ctxCallee)
        switch x.Op() {
        case ir.ODOTMETH:
+               x := x.(*ir.SelectorExpr)
                if base.Flag.LowerM != 0 {
                        base.WarnfAt(call.Pos(), "devirtualizing %v to %v", sel, typ)
                }
@@ -1372,6 +1392,7 @@ func devirtualizeCall(call *ir.CallExpr) {
                call.SetLeft(x)
        case ir.ODOTINTER:
                // Promoted method from embedded interface-typed field (#42279).
+               x := x.(*ir.SelectorExpr)
                if base.Flag.LowerM != 0 {
                        base.WarnfAt(call.Pos(), "partially devirtualizing %v to %v", sel, typ)
                }
index d2d908bf9f6f334fb136c2c0496922a02a801beb..4b7a22e6548f00b6d4023fc608eb453a80950dd4 100644 (file)
@@ -1169,6 +1169,7 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
        if stmt.Else != nil {
                e := p.stmt(stmt.Else)
                if e.Op() == ir.OBLOCK {
+                       e := e.(*ir.BlockStmt)
                        n.PtrRlist().Set(e.List().Slice())
                } else {
                        n.PtrRlist().Set1(e)
@@ -1319,12 +1320,16 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
                if ls != nil {
                        switch ls.Op() {
                        case ir.OFOR:
+                               ls := ls.(*ir.ForStmt)
                                ls.SetSym(sym)
                        case ir.ORANGE:
+                               ls := ls.(*ir.RangeStmt)
                                ls.SetSym(sym)
                        case ir.OSWITCH:
+                               ls := ls.(*ir.SwitchStmt)
                                ls.SetSym(sym)
                        case ir.OSELECT:
+                               ls := ls.(*ir.SelectStmt)
                                ls.SetSym(sym)
                        }
                }
@@ -1333,6 +1338,7 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
        l := []ir.Node{lhs}
        if ls != nil {
                if ls.Op() == ir.OBLOCK {
+                       ls := ls.(*ir.BlockStmt)
                        l = append(l, ls.List().Slice()...)
                } else {
                        l = append(l, ls)
index 2e7838c2527a18fbdecebc737511e34fe08cff99..96164d09fd5ef353a710c674dcb18b1625a3b187 100644 (file)
@@ -135,6 +135,7 @@ func (o *Order) cheapExpr(n ir.Node) ir.Node {
        case ir.ONAME, ir.OLITERAL, ir.ONIL:
                return n
        case ir.OLEN, ir.OCAP:
+               n := n.(*ir.UnaryExpr)
                l := o.cheapExpr(n.Left())
                if l == n.Left() {
                        return n
@@ -160,6 +161,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
                return n
 
        case ir.OLEN, ir.OCAP:
+               n := n.(*ir.UnaryExpr)
                l := o.safeExpr(n.Left())
                if l == n.Left() {
                        return n
@@ -169,6 +171,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
                return typecheck(a, ctxExpr)
 
        case ir.ODOT:
+               n := n.(*ir.SelectorExpr)
                l := o.safeExpr(n.Left())
                if l == n.Left() {
                        return n
@@ -178,6 +181,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
                return typecheck(a, ctxExpr)
 
        case ir.ODOTPTR:
+               n := n.(*ir.SelectorExpr)
                l := o.cheapExpr(n.Left())
                if l == n.Left() {
                        return n
@@ -187,6 +191,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
                return typecheck(a, ctxExpr)
 
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                l := o.cheapExpr(n.Left())
                if l == n.Left() {
                        return n
@@ -196,6 +201,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
                return typecheck(a, ctxExpr)
 
        case ir.OINDEX, ir.OINDEXMAP:
+               n := n.(*ir.IndexExpr)
                var l ir.Node
                if n.Left().Type().IsArray() {
                        l = o.safeExpr(n.Left())
@@ -281,9 +287,11 @@ func mapKeyReplaceStrConv(n ir.Node) bool {
        var replaced bool
        switch n.Op() {
        case ir.OBYTES2STR:
+               n := n.(*ir.ConvExpr)
                n.SetOp(ir.OBYTES2STRTMP)
                replaced = true
        case ir.OSTRUCTLIT:
+               n := n.(*ir.CompLitExpr)
                for _, elem := range n.List().Slice() {
                        elem := elem.(*ir.StructKeyExpr)
                        if mapKeyReplaceStrConv(elem.Left()) {
@@ -291,6 +299,7 @@ func mapKeyReplaceStrConv(n ir.Node) bool {
                        }
                }
        case ir.OARRAYLIT:
+               n := n.(*ir.CompLitExpr)
                for _, elem := range n.List().Slice() {
                        if elem.Op() == ir.OKEY {
                                elem = elem.(*ir.KeyExpr).Right()
@@ -499,6 +508,7 @@ func (o *Order) call(nn ir.Node) {
                // by copying it into a temp and marking that temp
                // still alive when we pop the temp stack.
                if arg.Op() == ir.OCONVNOP {
+                       arg := arg.(*ir.ConvExpr)
                        if arg.Left().Type().IsUnsafePtr() {
                                x := o.copyExpr(arg.Left())
                                arg.SetLeft(x)
@@ -512,6 +522,7 @@ func (o *Order) call(nn ir.Node) {
        for i, param := range n.Left().Type().Params().FieldSlice() {
                if param.Note == unsafeUintptrTag || param.Note == uintptrEscapesTag {
                        if arg := n.List().Index(i); arg.Op() == ir.OSLICELIT {
+                               arg := arg.(*ir.CompLitExpr)
                                for _, elt := range arg.List().Slice() {
                                        keepAlive(elt)
                                }
@@ -543,17 +554,20 @@ func (o *Order) mapAssign(n ir.Node) {
                base.Fatalf("order.mapAssign %v", n.Op())
 
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                if n.Left().Op() == ir.OINDEXMAP {
                        n.SetRight(o.safeMapRHS(n.Right()))
                }
                o.out = append(o.out, n)
        case ir.OASOP:
+               n := n.(*ir.AssignOpStmt)
                if n.Left().Op() == ir.OINDEXMAP {
                        n.SetRight(o.safeMapRHS(n.Right()))
                }
                o.out = append(o.out, n)
 
        case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2MAPR, ir.OAS2FUNC:
+               n := n.(*ir.AssignListStmt)
                var post []ir.Node
                for i, m := range n.List().Slice() {
                        switch {
@@ -583,6 +597,7 @@ func (o *Order) safeMapRHS(r ir.Node) ir.Node {
        // Make sure we evaluate the RHS before starting the map insert.
        // We need to make sure the RHS won't panic.  See issue 22881.
        if r.Op() == ir.OAPPEND {
+               r := r.(*ir.CallExpr)
                s := r.List().Slice()[1:]
                for i, n := range s {
                        s[i] = o.cheapExpr(n)
@@ -611,6 +626,7 @@ func (o *Order) stmt(n ir.Node) {
                o.out = append(o.out, n)
 
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), n.Left()))
@@ -618,6 +634,7 @@ func (o *Order) stmt(n ir.Node) {
                o.cleanTemp(t)
 
        case ir.OASOP:
+               n := n.(*ir.AssignOpStmt)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), nil))
@@ -632,6 +649,7 @@ func (o *Order) stmt(n ir.Node) {
                        l1 := o.safeExpr(n.Left())
                        l2 := ir.DeepCopy(src.NoXPos, l1)
                        if l2.Op() == ir.OINDEXMAP {
+                               l2 := l2.(*ir.IndexExpr)
                                l2.SetIndexMapLValue(false)
                        }
                        l2 = o.copyExpr(l2)
@@ -646,6 +664,7 @@ func (o *Order) stmt(n ir.Node) {
                o.cleanTemp(t)
 
        case ir.OAS2:
+               n := n.(*ir.AssignListStmt)
                t := o.markTemp()
                o.exprList(n.List())
                o.exprList(n.Rlist())
@@ -675,10 +694,13 @@ func (o *Order) stmt(n ir.Node) {
 
                switch r := n.Rlist().First(); r.Op() {
                case ir.ODOTTYPE2:
+                       r := r.(*ir.TypeAssertExpr)
                        r.SetLeft(o.expr(r.Left(), nil))
                case ir.ORECV:
+                       r := r.(*ir.UnaryExpr)
                        r.SetLeft(o.expr(r.Left(), nil))
                case ir.OINDEXMAP:
+                       r := r.(*ir.IndexExpr)
                        r.SetLeft(o.expr(r.Left(), nil))
                        r.SetRight(o.expr(r.Right(), nil))
                        // See similar conversion for OINDEXMAP below.
@@ -693,6 +715,7 @@ func (o *Order) stmt(n ir.Node) {
 
        // Special: does not save n onto out.
        case ir.OBLOCK:
+               n := n.(*ir.BlockStmt)
                o.stmtList(n.List())
 
        // Special: n->left is not an expression; save as is.
@@ -709,18 +732,21 @@ func (o *Order) stmt(n ir.Node) {
 
        // Special: handle call arguments.
        case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
+               n := n.(*ir.CallExpr)
                t := o.markTemp()
                o.call(n)
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
        case ir.OCLOSE, ir.ORECV:
+               n := n.(*ir.UnaryExpr)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
        case ir.OCOPY:
+               n := n.(*ir.BinaryExpr)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), nil))
@@ -728,6 +754,7 @@ func (o *Order) stmt(n ir.Node) {
                o.cleanTemp(t)
 
        case ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
+               n := n.(*ir.CallExpr)
                t := o.markTemp()
                o.exprList(n.List())
                o.out = append(o.out, n)
@@ -735,6 +762,7 @@ func (o *Order) stmt(n ir.Node) {
 
        // Special: order arguments to inner call but not call itself.
        case ir.ODEFER, ir.OGO:
+               n := n.(*ir.GoDeferStmt)
                t := o.markTemp()
                o.init(n.Left())
                o.call(n.Left())
@@ -742,6 +770,7 @@ func (o *Order) stmt(n ir.Node) {
                o.cleanTemp(t)
 
        case ir.ODELETE:
+               n := n.(*ir.CallExpr)
                t := o.markTemp()
                n.List().SetFirst(o.expr(n.List().First(), nil))
                n.List().SetSecond(o.expr(n.List().Second(), nil))
@@ -752,6 +781,7 @@ func (o *Order) stmt(n ir.Node) {
        // Clean temporaries from condition evaluation at
        // beginning of loop body and after for statement.
        case ir.OFOR:
+               n := n.(*ir.ForStmt)
                t := o.markTemp()
                n.SetLeft(o.exprInPlace(n.Left()))
                n.PtrBody().Prepend(o.cleanTempNoPop(t)...)
@@ -763,6 +793,7 @@ func (o *Order) stmt(n ir.Node) {
        // Clean temporaries from condition at
        // beginning of both branches.
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                t := o.markTemp()
                n.SetLeft(o.exprInPlace(n.Left()))
                n.PtrBody().Prepend(o.cleanTempNoPop(t)...)
@@ -775,6 +806,7 @@ func (o *Order) stmt(n ir.Node) {
        // Special: argument will be converted to interface using convT2E
        // so make sure it is an addressable temporary.
        case ir.OPANIC:
+               n := n.(*ir.UnaryExpr)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                if !n.Left().Type().IsInterface() {
@@ -858,6 +890,7 @@ func (o *Order) stmt(n ir.Node) {
                o.cleanTemp(t)
 
        case ir.ORETURN:
+               n := n.(*ir.ReturnStmt)
                o.exprList(n.List())
                o.out = append(o.out, n)
 
@@ -871,6 +904,7 @@ func (o *Order) stmt(n ir.Node) {
        // case (if p were nil, then the timing of the fault would
        // give this away).
        case ir.OSELECT:
+               n := n.(*ir.SelectStmt)
                t := o.markTemp()
                for _, ncas := range n.List().Slice() {
                        ncas := ncas.(*ir.CaseStmt)
@@ -932,6 +966,7 @@ func (o *Order) stmt(n ir.Node) {
                                orderBlock(ncas.PtrInit(), o.free)
 
                        case ir.OSEND:
+                               r := r.(*ir.SendStmt)
                                if r.Init().Len() != 0 {
                                        ir.DumpList("ninit", r.Init())
                                        base.Fatalf("ninit on select send")
@@ -969,6 +1004,7 @@ func (o *Order) stmt(n ir.Node) {
 
        // Special: value being sent is passed as a pointer; make it addressable.
        case ir.OSEND:
+               n := n.(*ir.SendStmt)
                t := o.markTemp()
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), nil))
@@ -1100,6 +1136,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                if haslit && hasbyte {
                        for _, n2 := range n.List().Slice() {
                                if n2.Op() == ir.OBYTES2STR {
+                                       n2 := n2.(*ir.ConvExpr)
                                        n2.SetOp(ir.OBYTES2STRTMP)
                                }
                        }
@@ -1107,6 +1144,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                return n
 
        case ir.OINDEXMAP:
+               n := n.(*ir.IndexExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), nil))
                needCopy := false
@@ -1134,6 +1172,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
        // concrete type (not interface) argument might need an addressable
        // temporary to pass to the runtime conversion routine.
        case ir.OCONVIFACE:
+               n := n.(*ir.ConvExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                if n.Left().Type().IsInterface() {
                        return n
@@ -1147,6 +1186,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                return n
 
        case ir.OCONVNOP:
+               n := n.(*ir.ConvExpr)
                if n.Type().IsKind(types.TUNSAFEPTR) && n.Left().Type().IsKind(types.TUINTPTR) && (n.Left().Op() == ir.OCALLFUNC || n.Left().Op() == ir.OCALLINTER || n.Left().Op() == ir.OCALLMETH) {
                        call := n.Left().(*ir.CallExpr)
                        // When reordering unsafe.Pointer(f()) into a separate
@@ -1172,6 +1212,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                // }
                // ... = r
 
+               n := n.(*ir.LogicalExpr)
                r := o.newTemp(n.Type(), false)
 
                // Evaluate left-hand side.
@@ -1233,6 +1274,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
 
        case ir.OAPPEND:
                // Check for append(x, make([]T, y)...) .
+               n := n.(*ir.CallExpr)
                if isAppendOfMake(n) {
                        n.List().SetFirst(o.expr(n.List().First(), nil)) // order x
                        mk := n.List().Second().(*ir.MakeExpr)
@@ -1247,6 +1289,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                return n
 
        case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
+               n := n.(*ir.SliceExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                low, high, max := n.SliceBounds()
                low = o.expr(low, nil)
@@ -1287,6 +1330,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                return n
 
        case ir.ODOTTYPE, ir.ODOTTYPE2:
+               n := n.(*ir.TypeAssertExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                if !isdirectiface(n.Type()) || instrumenting {
                        return o.copyExprClear(n)
@@ -1294,10 +1338,12 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                return n
 
        case ir.ORECV:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                return o.copyExprClear(n)
 
        case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+               n := n.(*ir.BinaryExpr)
                n.SetLeft(o.expr(n.Left(), nil))
                n.SetRight(o.expr(n.Right(), nil))
 
@@ -1338,6 +1384,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
                // Without this special case, order would otherwise compute all
                // the keys and values before storing any of them to the map.
                // See issue 26552.
+               n := n.(*ir.CompLitExpr)
                entries := n.List().Slice()
                statics := entries[:0]
                var dynamics []*ir.KeyExpr
index 8fe20a80fd9926836a38682d7b5d75f56b8deed1..f2d089fa4c7a4df61865992184fa6c728950f476 100644 (file)
@@ -81,6 +81,7 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
        ir.Visit(n, func(n ir.Node) {
                switch n.Op() {
                case ir.ONAME:
+                       n := n.(*ir.Name)
                        if n.Class() == ir.PFUNC {
                                if n != nil && n.Name().Defn != nil {
                                        if m := v.visit(n.Name().Defn.(*ir.Func)); m < min {
@@ -89,6 +90,7 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
                                }
                        }
                case ir.OMETHEXPR:
+                       n := n.(*ir.MethodExpr)
                        fn := methodExprName(n)
                        if fn != nil && fn.Defn != nil {
                                if m := v.visit(fn.Defn.(*ir.Func)); m < min {
@@ -96,6 +98,7 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
                                }
                        }
                case ir.ODOTMETH:
+                       n := n.(*ir.SelectorExpr)
                        fn := methodExprName(n)
                        if fn != nil && fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC && fn.Defn != nil {
                                if m := v.visit(fn.Defn.(*ir.Func)); m < min {
@@ -103,6 +106,7 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
                                }
                        }
                case ir.OCALLPART:
+                       n := n.(*ir.CallPartExpr)
                        fn := ir.AsNode(callpartMethod(n).Nname)
                        if fn != nil && fn.Op() == ir.ONAME {
                                if fn := fn.(*ir.Name); fn.Class() == ir.PFUNC && fn.Name().Defn != nil {
index be2f688eb9c0772f406b356a34c95a5e1605b552..64d3461dca4ae5a00b8dffe6102532acb8a7a750 100644 (file)
@@ -56,7 +56,9 @@ func typecheckselect(sel *ir.SelectStmt) {
                                // convert x = <-c into x, _ = <-c
                                // remove implicit conversions; the eventual assignment
                                // will reintroduce them.
+                               n := n.(*ir.AssignStmt)
                                if r := n.Right(); r.Op() == ir.OCONVNOP || r.Op() == ir.OCONVIFACE {
+                                       r := r.(*ir.ConvExpr)
                                        if r.Implicit() {
                                                n.SetRight(r.Left())
                                        }
@@ -68,6 +70,7 @@ func typecheckselect(sel *ir.SelectStmt) {
                                oselrecv2(n.Left(), n.Right(), n.Colas())
 
                        case ir.OAS2RECV:
+                               n := n.(*ir.AssignListStmt)
                                if n.Rlist().First().Op() != ir.ORECV {
                                        base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
                                        break
@@ -76,6 +79,7 @@ func typecheckselect(sel *ir.SelectStmt) {
 
                        case ir.ORECV:
                                // convert <-c into _, _ = <-c
+                               n := n.(*ir.UnaryExpr)
                                oselrecv2(ir.BlankNode, n, false)
 
                        case ir.OSEND:
@@ -162,10 +166,12 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
                }
                switch n.Op() {
                case ir.OSEND:
+                       n := n.(*ir.SendStmt)
                        n.SetRight(nodAddr(n.Right()))
                        n.SetRight(typecheck(n.Right(), ctxExpr))
 
                case ir.OSELRECV2:
+                       n := n.(*ir.AssignListStmt)
                        if !ir.IsBlank(n.List().First()) {
                                n.List().SetIndex(0, nodAddr(n.List().First()))
                                n.List().SetIndex(0, typecheck(n.List().First(), ctxExpr))
@@ -191,10 +197,12 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
 
                case ir.OSEND:
                        // if selectnbsend(c, v) { body } else { default body }
+                       n := n.(*ir.SendStmt)
                        ch := n.Left()
                        call = mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Right())
 
                case ir.OSELRECV2:
+                       n := n.(*ir.AssignListStmt)
                        recv := n.Rlist().First().(*ir.UnaryExpr)
                        ch := recv.Left()
                        elem := n.List().First()
@@ -261,11 +269,13 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
                default:
                        base.Fatalf("select %v", n.Op())
                case ir.OSEND:
+                       n := n.(*ir.SendStmt)
                        i = nsends
                        nsends++
                        c = n.Left()
                        elem = n.Right()
                case ir.OSELRECV2:
+                       n := n.(*ir.AssignListStmt)
                        nrecvs++
                        i = ncas - nrecvs
                        recv := n.Rlist().First().(*ir.UnaryExpr)
@@ -323,6 +333,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
                r := ir.NewIfStmt(base.Pos, cond, nil, nil)
 
                if n := cas.Left(); n != nil && n.Op() == ir.OSELRECV2 {
+                       n := n.(*ir.AssignListStmt)
                        if !ir.IsBlank(n.List().Second()) {
                                x := ir.NewAssignStmt(base.Pos, n.List().Second(), recvOK)
                                r.PtrBody().Append(typecheck(x, ctxStmt))
index 5a96d4c320f510ccad914304d06ae5a290c28797..f4988df9ac48ab12343aedec02ccd0265e337606 100644 (file)
@@ -127,6 +127,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
                return true
 
        case ir.OADDR:
+               r := r.(*ir.AddrExpr)
                if a := r.Left(); a.Op() == ir.ONAME {
                        a := a.(*ir.Name)
                        addrsym(l, loff, a, 0)
@@ -134,6 +135,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
                }
 
        case ir.OPTRLIT:
+               r := r.(*ir.AddrExpr)
                switch r.Left().Op() {
                case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
                        // copy pointer
@@ -148,6 +150,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
                return true
 
        case ir.OARRAYLIT, ir.OSTRUCTLIT:
+               r := r.(*ir.CompLitExpr)
                p := s.initplans[r]
                for i := range p.E {
                        e := &p.E[i]
@@ -202,6 +205,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
                return true
 
        case ir.OADDR:
+               r := r.(*ir.AddrExpr)
                if name, offset, ok := stataddr(r.Left()); ok {
                        addrsym(l, loff, name, offset)
                        return true
@@ -209,6 +213,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
                fallthrough
 
        case ir.OPTRLIT:
+               r := r.(*ir.AddrExpr)
                switch r.Left().Op() {
                case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
                        // Init pointer.
@@ -226,6 +231,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
                //dump("not static ptrlit", r);
 
        case ir.OSTR2BYTES:
+               r := r.(*ir.ConvExpr)
                if l.Class() == ir.PEXTERN && r.Left().Op() == ir.OLITERAL {
                        sval := ir.StringVal(r.Left())
                        slicebytes(l, loff, sval)
@@ -247,6 +253,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
                fallthrough
 
        case ir.OARRAYLIT, ir.OSTRUCTLIT:
+               r := r.(*ir.CompLitExpr)
                s.initplan(r)
 
                p := s.initplans[r]
@@ -287,6 +294,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
                // If you change something here, change it there, and vice versa.
 
                // Determine the underlying concrete type and value we are converting from.
+               r := r.(*ir.ConvExpr)
                val := ir.Node(r)
                for val.Op() == ir.OCONVIFACE {
                        val = val.(*ir.ConvExpr).Left()
@@ -467,6 +475,7 @@ func isStaticCompositeLiteral(n ir.Node) bool {
        case ir.OSLICELIT:
                return false
        case ir.OARRAYLIT:
+               n := n.(*ir.CompLitExpr)
                for _, r := range n.List().Slice() {
                        if r.Op() == ir.OKEY {
                                r = r.(*ir.KeyExpr).Right()
@@ -477,6 +486,7 @@ func isStaticCompositeLiteral(n ir.Node) bool {
                }
                return true
        case ir.OSTRUCTLIT:
+               n := n.(*ir.CompLitExpr)
                for _, r := range n.List().Slice() {
                        r := r.(*ir.StructKeyExpr)
                        if !isStaticCompositeLiteral(r.Left()) {
@@ -488,6 +498,7 @@ func isStaticCompositeLiteral(n ir.Node) bool {
                return true
        case ir.OCONVIFACE:
                // See staticassign's OCONVIFACE case for comments.
+               n := n.(*ir.ConvExpr)
                val := ir.Node(n)
                for val.Op() == ir.OCONVIFACE {
                        val = val.(*ir.ConvExpr).Left()
@@ -865,6 +876,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
                base.Fatalf("anylit: not lit, op=%v node=%v", n.Op(), n)
 
        case ir.ONAME:
+               n := n.(*ir.Name)
                appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, n))
 
        case ir.OMETHEXPR:
@@ -872,6 +884,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
                anylit(n.FuncName(), var_, init)
 
        case ir.OPTRLIT:
+               n := n.(*ir.AddrExpr)
                if !t.IsPtr() {
                        base.Fatalf("anylit: not ptr")
                }
@@ -1001,6 +1014,7 @@ func stataddr(n ir.Node) (name *ir.Name, offset int64, ok bool) {
                return stataddr(n.FuncName())
 
        case ir.ODOT:
+               n := n.(*ir.SelectorExpr)
                if name, offset, ok = stataddr(n.Left()); !ok {
                        break
                }
@@ -1008,6 +1022,7 @@ func stataddr(n ir.Node) (name *ir.Name, offset int64, ok bool) {
                return name, offset, true
 
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                if n.Left().Type().IsSlice() {
                        break
                }
@@ -1041,6 +1056,7 @@ func (s *InitSchedule) initplan(n ir.Node) {
                base.Fatalf("initplan")
 
        case ir.OARRAYLIT, ir.OSLICELIT:
+               n := n.(*ir.CompLitExpr)
                var k int64
                for _, a := range n.List().Slice() {
                        if a.Op() == ir.OKEY {
@@ -1056,6 +1072,7 @@ func (s *InitSchedule) initplan(n ir.Node) {
                }
 
        case ir.OSTRUCTLIT:
+               n := n.(*ir.CompLitExpr)
                for _, a := range n.List().Slice() {
                        if a.Op() != ir.OSTRUCTKEY {
                                base.Fatalf("initplan structlit")
@@ -1068,6 +1085,7 @@ func (s *InitSchedule) initplan(n ir.Node) {
                }
 
        case ir.OMAPLIT:
+               n := n.(*ir.CompLitExpr)
                for _, a := range n.List().Slice() {
                        if a.Op() != ir.OKEY {
                                base.Fatalf("initplan maplit")
@@ -1116,6 +1134,7 @@ func isZero(n ir.Node) bool {
                }
 
        case ir.OARRAYLIT:
+               n := n.(*ir.CompLitExpr)
                for _, n1 := range n.List().Slice() {
                        if n1.Op() == ir.OKEY {
                                n1 = n1.(*ir.KeyExpr).Right()
@@ -1127,6 +1146,7 @@ func isZero(n ir.Node) bool {
                return true
 
        case ir.OSTRUCTLIT:
+               n := n.(*ir.CompLitExpr)
                for _, n1 := range n.List().Slice() {
                        n1 := n1.(*ir.StructKeyExpr)
                        if !isZero(n1.Left()) {
index cc5f9eeea62ab4c703c746783a137eb5e6fb0565..dc3ea4be9eb3a80e4ae6b62d9382aa777274a559 100644 (file)
@@ -1150,6 +1150,7 @@ func (s *state) stmt(n ir.Node) {
        switch n.Op() {
 
        case ir.OBLOCK:
+               n := n.(*ir.BlockStmt)
                s.stmtList(n.List())
 
        // No-ops
@@ -1180,6 +1181,7 @@ func (s *state) stmt(n ir.Node) {
                        }
                }
        case ir.ODEFER:
+               n := n.(*ir.GoDeferStmt)
                if base.Debug.Defer > 0 {
                        var defertype string
                        if s.hasOpenDefers {
@@ -1201,9 +1203,11 @@ func (s *state) stmt(n ir.Node) {
                        s.callResult(n.Left().(*ir.CallExpr), d)
                }
        case ir.OGO:
+               n := n.(*ir.GoDeferStmt)
                s.callResult(n.Left().(*ir.CallExpr), callGo)
 
        case ir.OAS2DOTTYPE:
+               n := n.(*ir.AssignListStmt)
                res, resok := s.dottype(n.Rlist().First().(*ir.TypeAssertExpr), true)
                deref := false
                if !canSSAType(n.Rlist().First().Type()) {
@@ -1226,6 +1230,7 @@ func (s *state) stmt(n ir.Node) {
 
        case ir.OAS2FUNC:
                // We come here only when it is an intrinsic call returning two values.
+               n := n.(*ir.AssignListStmt)
                call := n.Rlist().First().(*ir.CallExpr)
                if !IsIntrinsicCall(call) {
                        s.Fatalf("non-intrinsic AS2FUNC not expanded %v", call)
@@ -1238,11 +1243,13 @@ func (s *state) stmt(n ir.Node) {
                return
 
        case ir.ODCL:
+               n := n.(*ir.Decl)
                if n.Left().(*ir.Name).Class() == ir.PAUTOHEAP {
                        s.Fatalf("DCL %v", n)
                }
 
        case ir.OLABEL:
+               n := n.(*ir.LabelStmt)
                sym := n.Sym()
                lab := s.label(sym)
 
@@ -1260,6 +1267,7 @@ func (s *state) stmt(n ir.Node) {
                s.startBlock(lab.target)
 
        case ir.OGOTO:
+               n := n.(*ir.BranchStmt)
                sym := n.Sym()
 
                lab := s.label(sym)
@@ -1272,6 +1280,7 @@ func (s *state) stmt(n ir.Node) {
                b.AddEdgeTo(lab.target)
 
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                if n.Left() == n.Right() && n.Left().Op() == ir.ONAME {
                        // An x=x assignment. No point in doing anything
                        // here. In addition, skipping this assignment
@@ -1356,6 +1365,7 @@ func (s *state) stmt(n ir.Node) {
                if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && samesafeexpr(rhs.(*ir.SliceExpr).Left(), n.Left()) {
                        // We're assigning a slicing operation back to its source.
                        // Don't write back fields we aren't changing. See issue #14855.
+                       rhs := rhs.(*ir.SliceExpr)
                        i, j, k := rhs.SliceBounds()
                        if i != nil && (i.Op() == ir.OLITERAL && i.Val().Kind() == constant.Int && ir.Int64Val(i) == 0) {
                                // [0:...] is the same as [:...]
@@ -1385,6 +1395,7 @@ func (s *state) stmt(n ir.Node) {
                s.assign(n.Left(), r, deref, skip)
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                if ir.IsConst(n.Left(), constant.Bool) {
                        s.stmtList(n.Left().Init())
                        if ir.BoolVal(n.Left()) {
@@ -1431,16 +1442,19 @@ func (s *state) stmt(n ir.Node) {
                s.startBlock(bEnd)
 
        case ir.ORETURN:
+               n := n.(*ir.ReturnStmt)
                s.stmtList(n.List())
                b := s.exit()
                b.Pos = s.lastPos.WithIsStmt()
 
        case ir.ORETJMP:
+               n := n.(*ir.BranchStmt)
                b := s.exit()
                b.Kind = ssa.BlockRetJmp // override BlockRet
                b.Aux = callTargetLSym(n.Sym(), s.curfn.LSym)
 
        case ir.OCONTINUE, ir.OBREAK:
+               n := n.(*ir.BranchStmt)
                var to *ssa.Block
                if n.Sym() == nil {
                        // plain break/continue
@@ -1472,6 +1486,7 @@ func (s *state) stmt(n ir.Node) {
                //
                // OFORUNTIL: for Ninit; Left; Right; List { Nbody }
                // => body: { Nbody }; incr: Right; if Left { lateincr: List; goto body }; end:
+               n := n.(*ir.ForStmt)
                bCond := s.f.NewBlock(ssa.BlockPlain)
                bBody := s.f.NewBlock(ssa.BlockPlain)
                bIncr := s.f.NewBlock(ssa.BlockPlain)
@@ -1600,6 +1615,7 @@ func (s *state) stmt(n ir.Node) {
                s.startBlock(bEnd)
 
        case ir.OVARDEF:
+               n := n.(*ir.UnaryExpr)
                if !s.canSSA(n.Left()) {
                        s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.Left().(*ir.Name), s.mem(), false)
                }
@@ -1608,12 +1624,14 @@ func (s *state) stmt(n ir.Node) {
                // We only care about liveness info at call sites, so putting the
                // varkill in the store chain is enough to keep it correctly ordered
                // with respect to call ops.
+               n := n.(*ir.UnaryExpr)
                if !s.canSSA(n.Left()) {
                        s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.Left().(*ir.Name), s.mem(), false)
                }
 
        case ir.OVARLIVE:
                // Insert a varlive op to record that a variable is still live.
+               n := n.(*ir.UnaryExpr)
                v := n.Left().(*ir.Name)
                if !v.Addrtaken() {
                        s.Fatalf("VARLIVE variable %v must have Addrtaken set", v)
@@ -1626,10 +1644,12 @@ func (s *state) stmt(n ir.Node) {
                s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, v, s.mem())
 
        case ir.OCHECKNIL:
+               n := n.(*ir.UnaryExpr)
                p := s.expr(n.Left())
                s.nilCheck(p)
 
        case ir.OINLMARK:
+               n := n.(*ir.InlineMarkStmt)
                s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Offset(), s.mem())
 
        default:
@@ -2097,16 +2117,19 @@ func (s *state) expr(n ir.Node) *ssa.Value {
        s.stmtList(n.Init())
        switch n.Op() {
        case ir.OBYTES2STRTMP:
+               n := n.(*ir.ConvExpr)
                slice := s.expr(n.Left())
                ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice)
                len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
                return s.newValue2(ssa.OpStringMake, n.Type(), ptr, len)
        case ir.OSTR2BYTESTMP:
+               n := n.(*ir.ConvExpr)
                str := s.expr(n.Left())
                ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str)
                len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], str)
                return s.newValue3(ssa.OpSliceMake, n.Type(), ptr, len, len)
        case ir.OCFUNC:
+               n := n.(*ir.UnaryExpr)
                aux := n.Left().Sym().Linksym()
                return s.entryNewValue1A(ssa.OpAddr, n.Type(), aux, s.sb)
        case ir.OMETHEXPR:
@@ -2114,6 +2137,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                sym := funcsym(n.FuncName().Sym()).Linksym()
                return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type()), sym, s.sb)
        case ir.ONAME:
+               n := n.(*ir.Name)
                if n.Class() == ir.PFUNC {
                        // "value" of a function is the address of the function's closure
                        sym := funcsym(n.Sym()).Linksym()
@@ -2135,6 +2159,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                addr := s.addr(n)
                return s.load(n.Type(), addr)
        case ir.ONIL:
+               n := n.(*ir.NilExpr)
                t := n.Type()
                switch {
                case t.IsSlice():
@@ -2203,6 +2228,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                        return nil
                }
        case ir.OCONVNOP:
+               n := n.(*ir.ConvExpr)
                to := n.Type()
                from := n.Left().Type()
 
@@ -2271,6 +2297,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                return v
 
        case ir.OCONV:
+               n := n.(*ir.ConvExpr)
                x := s.expr(n.Left())
                ft := n.Left().Type() // from type
                tt := n.Type()        // to type
@@ -2448,6 +2475,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
 
        // binary ops
        case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                if n.Left().Type().IsComplex() {
@@ -2481,6 +2509,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                // integer comparison
                return s.newValue2(s.ssaOp(op, n.Left().Type()), types.Types[types.TBOOL], a, b)
        case ir.OMUL:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                if n.Type().IsComplex() {
@@ -2520,6 +2549,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b)
 
        case ir.ODIV:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                if n.Type().IsComplex() {
@@ -2567,10 +2597,12 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
                return s.intDivide(n, a, b)
        case ir.OMOD:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                return s.intDivide(n, a, b)
        case ir.OADD, ir.OSUB:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                if n.Type().IsComplex() {
@@ -2585,15 +2617,18 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
                return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b)
        case ir.OAND, ir.OOR, ir.OXOR:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b)
        case ir.OANDNOT:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                b = s.newValue1(s.ssaOp(ir.OBITNOT, b.Type), b.Type, b)
                return s.newValue2(s.ssaOp(ir.OAND, n.Type()), a.Type, a, b)
        case ir.OLSH, ir.ORSH:
+               n := n.(*ir.BinaryExpr)
                a := s.expr(n.Left())
                b := s.expr(n.Right())
                bt := b.Type
@@ -2617,6 +2652,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                //     }
                // Using var in the subsequent block introduces the
                // necessary phi variable.
+               n := n.(*ir.LogicalExpr)
                el := s.expr(n.Left())
                s.vars[n] = el
 
@@ -2648,12 +2684,14 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                s.startBlock(bResult)
                return s.variable(n, types.Types[types.TBOOL])
        case ir.OCOMPLEX:
+               n := n.(*ir.BinaryExpr)
                r := s.expr(n.Left())
                i := s.expr(n.Right())
                return s.newValue2(ssa.OpComplexMake, n.Type(), r, i)
 
        // unary ops
        case ir.ONEG:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                if n.Type().IsComplex() {
                        tp := floatForComplex(n.Type())
@@ -2664,18 +2702,23 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
                return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a)
        case ir.ONOT, ir.OBITNOT:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a)
        case ir.OIMAG, ir.OREAL:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                return s.newValue1(s.ssaOp(n.Op(), n.Left().Type()), n.Type(), a)
        case ir.OPLUS:
+               n := n.(*ir.UnaryExpr)
                return s.expr(n.Left())
 
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                return s.addr(n.Left())
 
        case ir.ORESULT:
+               n := n.(*ir.ResultExpr)
                if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
                        // Do the old thing
                        addr := s.constOffPtrSP(types.NewPtr(n.Type()), n.Offset())
@@ -2695,6 +2738,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
 
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                p := s.exprPtr(n.Left(), n.Bounded(), n.Pos())
                return s.load(n.Type(), p)
 
@@ -2721,11 +2765,13 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                return s.newValue1I(ssa.OpStructSelect, n.Type(), int64(fieldIdx(n)), v)
 
        case ir.ODOTPTR:
+               n := n.(*ir.SelectorExpr)
                p := s.exprPtr(n.Left(), n.Bounded(), n.Pos())
                p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type()), n.Offset(), p)
                return s.load(n.Type(), p)
 
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                switch {
                case n.Left().Type().IsString():
                        if n.Bounded() && ir.IsConst(n.Left(), constant.String) && ir.IsConst(n.Right(), constant.Int) {
@@ -2792,6 +2838,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
 
        case ir.OSPTR:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                if n.Left().Type().IsSlice() {
                        return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
@@ -2800,25 +2847,30 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                }
 
        case ir.OITAB:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                return s.newValue1(ssa.OpITab, n.Type(), a)
 
        case ir.OIDATA:
+               n := n.(*ir.UnaryExpr)
                a := s.expr(n.Left())
                return s.newValue1(ssa.OpIData, n.Type(), a)
 
        case ir.OEFACE:
+               n := n.(*ir.BinaryExpr)
                tab := s.expr(n.Left())
                data := s.expr(n.Right())
                return s.newValue2(ssa.OpIMake, n.Type(), tab, data)
 
        case ir.OSLICEHEADER:
+               n := n.(*ir.SliceHeaderExpr)
                p := s.expr(n.Left())
                l := s.expr(n.List().First())
                c := s.expr(n.List().Second())
                return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
 
        case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
+               n := n.(*ir.SliceExpr)
                v := s.expr(n.Left())
                var i, j, k *ssa.Value
                low, high, max := n.SliceBounds()
@@ -2835,6 +2887,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
 
        case ir.OSLICESTR:
+               n := n.(*ir.SliceExpr)
                v := s.expr(n.Left())
                var i, j *ssa.Value
                low, high, _ := n.SliceBounds()
@@ -2859,6 +2912,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                return s.callResult(n, callNormal)
 
        case ir.OGETG:
+               n := n.(*ir.CallExpr)
                return s.newValue1(ssa.OpGetG, n.Type(), s.mem())
 
        case ir.OAPPEND:
@@ -2868,12 +2922,14 @@ func (s *state) expr(n ir.Node) *ssa.Value {
                // All literals with nonzero fields have already been
                // rewritten during walk. Any that remain are just T{}
                // or equivalents. Use the zero value.
+               n := n.(*ir.CompLitExpr)
                if !isZero(n) {
                        s.Fatalf("literal with nonzero value in SSA: %v", n)
                }
                return s.zeroVal(n.Type())
 
        case ir.ONEWOBJ:
+               n := n.(*ir.UnaryExpr)
                if n.Type().Elem().Size() == 0 {
                        return s.newValue1A(ssa.OpAddr, n.Type(), zerobaseSym, s.sb)
                }
@@ -3057,6 +3113,7 @@ func (s *state) append(n *ir.CallExpr, inplace bool) *ssa.Value {
 func (s *state) condBranch(cond ir.Node, yes, no *ssa.Block, likely int8) {
        switch cond.Op() {
        case ir.OANDAND:
+               cond := cond.(*ir.LogicalExpr)
                mid := s.f.NewBlock(ssa.BlockPlain)
                s.stmtList(cond.Init())
                s.condBranch(cond.Left(), mid, no, max8(likely, 0))
@@ -3070,6 +3127,7 @@ func (s *state) condBranch(cond ir.Node, yes, no *ssa.Block, likely int8) {
                // TODO: have the frontend give us branch prediction hints for
                // OANDAND and OOROR nodes (if it ever has such info).
        case ir.OOROR:
+               cond := cond.(*ir.LogicalExpr)
                mid := s.f.NewBlock(ssa.BlockPlain)
                s.stmtList(cond.Init())
                s.condBranch(cond.Left(), yes, mid, min8(likely, 0))
@@ -3080,10 +3138,12 @@ func (s *state) condBranch(cond ir.Node, yes, no *ssa.Block, likely int8) {
                // If likely==1, then we don't have enough info to decide
                // the likelihood of the first branch.
        case ir.ONOT:
+               cond := cond.(*ir.UnaryExpr)
                s.stmtList(cond.Init())
                s.condBranch(cond.Left(), no, yes, -likely)
                return
        case ir.OCONVNOP:
+               cond := cond.(*ir.ConvExpr)
                s.stmtList(cond.Init())
                s.condBranch(cond.Left(), yes, no, likely)
                return
@@ -3157,6 +3217,7 @@ func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask
                        return
                }
                if left.Op() == ir.OINDEX && left.(*ir.IndexExpr).Left().Type().IsArray() {
+                       left := left.(*ir.IndexExpr)
                        s.pushLine(left.Pos())
                        defer s.popLine()
                        // We're assigning to an element of an ssa-able array.
@@ -4630,6 +4691,7 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
        case ir.OCALLFUNC:
                testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
                if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class() == ir.PFUNC {
+                       fn := fn.(*ir.Name)
                        sym = fn.Sym()
                        break
                }
@@ -5000,6 +5062,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
                }
        case ir.ORESULT:
                // load return from callee
+               n := n.(*ir.ResultExpr)
                if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
                        return s.constOffPtrSP(t, n.Offset())
                }
@@ -5012,6 +5075,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
                return x
 
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                if n.Left().Type().IsSlice() {
                        a := s.expr(n.Left())
                        i := s.expr(n.Right())
@@ -5027,11 +5091,14 @@ func (s *state) addr(n ir.Node) *ssa.Value {
                        return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left().Type().Elem()), a, i)
                }
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                return s.exprPtr(n.Left(), n.Bounded(), n.Pos())
        case ir.ODOT:
+               n := n.(*ir.SelectorExpr)
                p := s.addr(n.Left())
                return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
        case ir.ODOTPTR:
+               n := n.(*ir.SelectorExpr)
                p := s.exprPtr(n.Left(), n.Bounded(), n.Pos())
                return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
        case ir.OCLOSUREREAD:
@@ -5039,6 +5106,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
                return s.newValue1I(ssa.OpOffPtr, t, n.Offset(),
                        s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr))
        case ir.OCONVNOP:
+               n := n.(*ir.ConvExpr)
                if n.Type() == n.Left().Type() {
                        return s.addr(n.Left())
                }
@@ -5072,10 +5140,12 @@ func (s *state) canSSA(n ir.Node) bool {
        for {
                nn := n
                if nn.Op() == ir.ODOT {
+                       nn := nn.(*ir.SelectorExpr)
                        n = nn.Left()
                        continue
                }
                if nn.Op() == ir.OINDEX {
+                       nn := nn.(*ir.IndexExpr)
                        if nn.Left().Type().IsArray() {
                                n = nn.Left()
                                continue
@@ -7297,11 +7367,13 @@ func (e *ssafn) MyImportPath() string {
 
 func clobberBase(n ir.Node) ir.Node {
        if n.Op() == ir.ODOT {
+               n := n.(*ir.SelectorExpr)
                if n.Left().Type().NumFields() == 1 {
                        return clobberBase(n.Left())
                }
        }
        if n.Op() == ir.OINDEX {
+               n := n.(*ir.IndexExpr)
                if n.Left().Type().IsArray() && n.Left().Type().NumElem() == 1 {
                        return clobberBase(n.Left())
                }
index 174452def23087f48eafdab53a95cc9b075cbc25..5aebae0b18bcd82140cb9b9b0a3bc0205cd1b823 100644 (file)
@@ -612,6 +612,7 @@ func calcHasCall(n ir.Node) bool {
                return true
        case ir.OANDAND, ir.OOROR:
                // hard with instrumented code
+               n := n.(*ir.LogicalExpr)
                if instrumenting {
                        return true
                }
@@ -625,42 +626,52 @@ func calcHasCall(n ir.Node) bool {
        // When using soft-float, these ops might be rewritten to function calls
        // so we ensure they are evaluated first.
        case ir.OADD, ir.OSUB, ir.OMUL:
+               n := n.(*ir.BinaryExpr)
                if thearch.SoftFloat && (isFloat[n.Type().Kind()] || isComplex[n.Type().Kind()]) {
                        return true
                }
                return n.Left().HasCall() || n.Right().HasCall()
        case ir.ONEG:
+               n := n.(*ir.UnaryExpr)
                if thearch.SoftFloat && (isFloat[n.Type().Kind()] || isComplex[n.Type().Kind()]) {
                        return true
                }
                return n.Left().HasCall()
        case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
+               n := n.(*ir.BinaryExpr)
                if thearch.SoftFloat && (isFloat[n.Left().Type().Kind()] || isComplex[n.Left().Type().Kind()]) {
                        return true
                }
                return n.Left().HasCall() || n.Right().HasCall()
        case ir.OCONV:
+               n := n.(*ir.ConvExpr)
                if thearch.SoftFloat && ((isFloat[n.Type().Kind()] || isComplex[n.Type().Kind()]) || (isFloat[n.Left().Type().Kind()] || isComplex[n.Left().Type().Kind()])) {
                        return true
                }
                return n.Left().HasCall()
 
        case ir.OAND, ir.OANDNOT, ir.OLSH, ir.OOR, ir.ORSH, ir.OXOR, ir.OCOPY, ir.OCOMPLEX, ir.OEFACE:
+               n := n.(*ir.BinaryExpr)
                return n.Left().HasCall() || n.Right().HasCall()
 
        case ir.OAS:
+               n := n.(*ir.AssignStmt)
                return n.Left().HasCall() || n.Right() != nil && n.Right().HasCall()
 
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                return n.Left().HasCall()
        case ir.OPAREN:
+               n := n.(*ir.ParenExpr)
                return n.Left().HasCall()
        case ir.OBITNOT, ir.ONOT, ir.OPLUS, ir.ORECV,
                ir.OALIGNOF, ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.ONEW,
                ir.OOFFSETOF, ir.OPANIC, ir.OREAL, ir.OSIZEOF,
                ir.OCHECKNIL, ir.OCFUNC, ir.OIDATA, ir.OITAB, ir.ONEWOBJ, ir.OSPTR, ir.OVARDEF, ir.OVARKILL, ir.OVARLIVE:
+               n := n.(*ir.UnaryExpr)
                return n.Left().HasCall()
        case ir.ODOT, ir.ODOTMETH, ir.ODOTINTER:
+               n := n.(*ir.SelectorExpr)
                return n.Left().HasCall()
 
        case ir.OGETG, ir.OCLOSUREREAD, ir.OMETHEXPR:
@@ -675,12 +686,15 @@ func calcHasCall(n ir.Node) bool {
                return false
        case ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.OBYTES2STRTMP, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2BYTESTMP, ir.OSTR2RUNES, ir.ORUNESTR:
                // TODO(rsc): Some conversions are themselves calls, no?
+               n := n.(*ir.ConvExpr)
                return n.Left().HasCall()
        case ir.ODOTTYPE2:
                // TODO(rsc): Shouldn't this be up with ODOTTYPE above?
+               n := n.(*ir.TypeAssertExpr)
                return n.Left().HasCall()
        case ir.OSLICEHEADER:
                // TODO(rsc): What about len and cap?
+               n := n.(*ir.SliceHeaderExpr)
                return n.Left().HasCall()
        case ir.OAS2DOTTYPE, ir.OAS2FUNC:
                // TODO(rsc): Surely we need to check List and Rlist.
@@ -768,6 +782,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.OLEN, ir.OCAP:
+               n := n.(*ir.UnaryExpr)
                l := safeexpr(n.Left(), init)
                if l == n.Left() {
                        return n
@@ -777,6 +792,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(a, ctxExpr), init)
 
        case ir.ODOT, ir.ODOTPTR:
+               n := n.(*ir.SelectorExpr)
                l := safeexpr(n.Left(), init)
                if l == n.Left() {
                        return n
@@ -786,6 +802,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(a, ctxExpr), init)
 
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                l := safeexpr(n.Left(), init)
                if l == n.Left() {
                        return n
@@ -795,6 +812,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(a, ctxExpr), init)
 
        case ir.OINDEX, ir.OINDEXMAP:
+               n := n.(*ir.IndexExpr)
                l := safeexpr(n.Left(), init)
                r := safeexpr(n.Right(), init)
                if l == n.Left() && r == n.Right() {
@@ -806,6 +824,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(a, ctxExpr), init)
 
        case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT:
+               n := n.(*ir.CompLitExpr)
                if isStaticCompositeLiteral(n) {
                        return n
                }
index 1866a6a784a6b324053237c67241989ada56541c..7cd1c16e00f1d64ba72fac13ffc63f3d676c2a91 100644 (file)
@@ -266,6 +266,7 @@ func walkExprSwitch(sw *ir.SwitchStmt) {
        // conversion into a runtime call.
        // See issue 24937 for more discussion.
        if cond.Op() == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
+               cond := cond.(*ir.ConvExpr)
                cond.SetOp(ir.OBYTES2STRTMP)
        }
 
index db03fd9e7534008bc72a979be155283606107205..bb5e9fad1e0070c0b82680f07f3ff35e8c9b7bdd 100644 (file)
@@ -412,6 +412,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
                switch n.Op() {
                // We can already diagnose variables used as types.
                case ir.ONAME:
+                       n := n.(*ir.Name)
                        if top&(ctxExpr|ctxType) == ctxType {
                                base.Errorf("%v is not a type", n)
                        }
@@ -477,6 +478,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
        isMulti := false
        switch n.Op() {
        case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
+               n := n.(*ir.CallExpr)
                if t := n.Left().Type(); t != nil && t.Kind() == types.TFUNC {
                        nr := t.NumResults()
                        isMulti = nr > 1
@@ -577,6 +579,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                }
 
                if n.Op() == ir.ONAME {
+                       n := n.(*ir.Name)
                        if n.SubOp() != 0 && top&ctxCallee == 0 {
                                base.Errorf("use of builtin %v not in function call", n.Sym())
                                n.SetType(nil)
@@ -608,6 +611,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ONAME:
+               n := n.(*ir.Name)
                if n.Name().Decldepth == 0 {
                        n.Name().Decldepth = decldepth
                }
@@ -630,6 +634,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OPACK:
+               n := n.(*ir.PkgName)
                base.Errorf("use of package %v without selector", n.Sym())
                n.SetType(nil)
                return n
@@ -816,6 +821,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                }
                op := n.Op()
                if n.Op() == ir.OASOP {
+                       n := n.(*ir.AssignOpStmt)
                        checkassign(n, l)
                        if n.Implicit() && !okforarith[l.Type().Kind()] {
                                base.Errorf("invalid operation: %v (non-numeric type %v)", n, l.Type())
@@ -859,6 +865,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                // can't be used with "&&" than to report that "x == x" (type untyped bool)
                // can't be converted to int (see issue #41500).
                if n.Op() == ir.OANDAND || n.Op() == ir.OOROR {
+                       n := n.(*ir.LogicalExpr)
                        if !n.Left().Type().IsBoolean() {
                                base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Left().Type()))
                                n.SetType(nil)
@@ -1010,6 +1017,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
 
                if et == types.TSTRING && n.Op() == ir.OADD {
                        // create or update OADDSTR node with list of strings in x + y + z + (w + v) + ...
+                       n := n.(*ir.BinaryExpr)
                        var add *ir.AddStringExpr
                        if l.Op() == ir.OADDSTR {
                                add = l.(*ir.AddStringExpr)
@@ -1018,6 +1026,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                                add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l})
                        }
                        if r.Op() == ir.OADDSTR {
+                               r := r.(*ir.AddStringExpr)
                                add.PtrList().AppendNodes(r.PtrList())
                        } else {
                                add.PtrList().Append(r)
@@ -1038,6 +1047,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                l := n.Left()
                t := l.Type()
@@ -1056,6 +1066,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
 
        // exprs
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                if n.Left().Type() == nil {
                        n.SetType(nil)
@@ -1070,6 +1081,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                        checklvalue(n.Left(), "take the address of")
                        r := outervalue(n.Left())
                        if r.Op() == ir.ONAME {
+                               r := r.(*ir.Name)
                                if ir.Orig(r) != r {
                                        base.Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean?
                                }
@@ -1170,6 +1182,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ODOTTYPE:
+               n := n.(*ir.TypeAssertExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                l := n.Left()
@@ -1215,6 +1228,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                n.SetLeft(implicitstar(n.Left()))
@@ -1273,6 +1287,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ORECV:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                l := n.Left()
@@ -1297,6 +1312,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OSEND:
+               n := n.(*ir.SendStmt)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetRight(typecheck(n.Right(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
@@ -1325,6 +1341,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                // can construct an OSLICEHEADER node.
                // Components used in OSLICEHEADER that are supplied by parsed source code
                // have already been typechecked in e.g. OMAKESLICE earlier.
+               n := n.(*ir.SliceHeaderExpr)
                t := n.Type()
                if t == nil {
                        base.Fatalf("no type specified for OSLICEHEADER")
@@ -1369,6 +1386,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                // can construct an OMAKESLICECOPY node.
                // Components used in OMAKESCLICECOPY that are supplied by parsed source code
                // have already been typechecked in OMAKE and OCOPY earlier.
+               n := n.(*ir.MakeExpr)
                t := n.Type()
 
                if t == nil {
@@ -1407,6 +1425,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OSLICE, ir.OSLICE3:
+               n := n.(*ir.SliceExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                low, high, max := n.SliceBounds()
                hasmax := n.Op().IsSlice3()
@@ -1496,6 +1515,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                l := n.Left()
 
                if l.Op() == ir.ONAME && l.(*ir.Name).SubOp() != 0 {
+                       l := l.(*ir.Name)
                        if n.IsDDD() && l.SubOp() != ir.OAPPEND {
                                base.Errorf("invalid use of ... with builtin %v", l)
                        }
@@ -1571,6 +1591,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                        n.SetOp(ir.OCALLINTER)
 
                case ir.ODOTMETH:
+                       l := l.(*ir.SelectorExpr)
                        n.SetOp(ir.OCALLMETH)
 
                        // typecheckaste was used here but there wasn't enough
@@ -1632,10 +1653,12 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+               n := n.(*ir.UnaryExpr)
                n.SetType(types.Types[types.TUINTPTR])
                return n
 
        case ir.OCAP, ir.OLEN:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                n.SetLeft(implicitstar(n.Left()))
@@ -1662,6 +1685,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OREAL, ir.OIMAG:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                l := n.Left()
                t := l.Type()
@@ -1686,6 +1710,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OCOMPLEX:
+               n := n.(*ir.BinaryExpr)
                l := typecheck(n.Left(), ctxExpr)
                r := typecheck(n.Right(), ctxExpr)
                if l.Type() == nil || r.Type() == nil {
@@ -1726,6 +1751,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OCLOSE:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                l := n.Left()
@@ -1748,6 +1774,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ODELETE:
+               n := n.(*ir.CallExpr)
                typecheckargs(n)
                args := n.List()
                if args.Len() == 0 {
@@ -1780,6 +1807,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OAPPEND:
+               n := n.(*ir.CallExpr)
                typecheckargs(n)
                args := n.List()
                if args.Len() == 0 {
@@ -1840,6 +1868,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OCOPY:
+               n := n.(*ir.BinaryExpr)
                n.SetType(types.Types[types.TINT])
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
@@ -1925,6 +1954,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OMAKE:
+               n := n.(*ir.CallExpr)
                args := n.List().Slice()
                if len(args) == 0 {
                        base.Errorf("missing argument to make")
@@ -2032,6 +2062,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return nn
 
        case ir.ONEW:
+               n := n.(*ir.UnaryExpr)
                if n.Left() == nil {
                        // Fatalf because the OCALL above checked for us,
                        // so this must be an internally-generated mistake.
@@ -2049,6 +2080,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OPRINT, ir.OPRINTN:
+               n := n.(*ir.CallExpr)
                typecheckargs(n)
                ls := n.List().Slice()
                for i1, n1 := range ls {
@@ -2062,6 +2094,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OPANIC:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), types.Types[types.TINTER]))
                if n.Left().Type() == nil {
@@ -2071,6 +2104,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ORECOVER:
+               n := n.(*ir.CallExpr)
                if n.List().Len() != 0 {
                        base.Errorf("too many arguments to recover")
                        n.SetType(nil)
@@ -2089,6 +2123,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OITAB:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                t := n.Left().Type()
                if t == nil {
@@ -2104,10 +2139,12 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
        case ir.OIDATA:
                // Whoever creates the OIDATA node must know a priori the concrete type at that moment,
                // usually by just having checked the OITAB.
+               n := n.(*ir.UnaryExpr)
                base.Fatalf("cannot typecheck interface data %v", n)
                panic("unreachable")
 
        case ir.OSPTR:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                t := n.Left().Type()
                if t == nil {
@@ -2128,11 +2165,13 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OCFUNC:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetType(types.Types[types.TUINTPTR])
                return n
 
        case ir.OCONVNOP:
+               n := n.(*ir.ConvExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                return n
 
@@ -2161,6 +2200,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OBLOCK:
+               n := n.(*ir.BlockStmt)
                typecheckslice(n.List().Slice(), ctxStmt)
                return n
 
@@ -2183,6 +2223,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OFOR, ir.OFORUNTIL:
+               n := n.(*ir.ForStmt)
                typecheckslice(n.Init().Slice(), ctxStmt)
                decldepth++
                n.SetLeft(typecheck(n.Left(), ctxExpr))
@@ -2202,6 +2243,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                typecheckslice(n.Init().Slice(), ctxStmt)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
@@ -2216,6 +2258,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ORETURN:
+               n := n.(*ir.ReturnStmt)
                typecheckargs(n)
                if Curfn == nil {
                        base.Errorf("return outside function")
@@ -2230,6 +2273,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ORETJMP:
+               n := n.(*ir.BranchStmt)
                return n
 
        case ir.OSELECT:
@@ -2245,6 +2289,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.OTYPESW:
+               n := n.(*ir.TypeSwitchGuard)
                base.Errorf("use of .(type) outside type switch")
                n.SetType(nil)
                return n
@@ -2254,10 +2299,12 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                return n
 
        case ir.ODCLCONST:
+               n := n.(*ir.Decl)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                return n
 
        case ir.ODCLTYPE:
+               n := n.(*ir.Decl)
                n.SetLeft(typecheck(n.Left(), ctxType))
                checkwidth(n.Left().Type())
                return n
@@ -2814,6 +2861,7 @@ notenough:
                        // Method expressions have the form T.M, and the compiler has
                        // rewritten those to ONAME nodes but left T in Left.
                        if call.Op() == ir.OMETHEXPR {
+                               call := call.(*ir.MethodExpr)
                                base.Errorf("not enough arguments in call to method expression %v%s", call, details)
                        } else {
                                base.Errorf("not enough arguments in call to %v%s", call, details)
@@ -3231,6 +3279,7 @@ func nonexported(sym *types.Sym) bool {
 func islvalue(n ir.Node) bool {
        switch n.Op() {
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                if n.Left().Type() != nil && n.Left().Type().IsArray() {
                        return islvalue(n.Left())
                }
@@ -3242,9 +3291,11 @@ func islvalue(n ir.Node) bool {
                return true
 
        case ir.ODOT:
+               n := n.(*ir.SelectorExpr)
                return islvalue(n.Left())
 
        case ir.ONAME:
+               n := n.(*ir.Name)
                if n.Class() == ir.PFUNC {
                        return false
                }
@@ -3268,6 +3319,7 @@ func checkassign(stmt ir.Node, n ir.Node) {
        if !ir.DeclaredBy(n, stmt) || stmt.Op() == ir.ORANGE {
                r := outervalue(n)
                if r.Op() == ir.ONAME {
+                       r := r.(*ir.Name)
                        r.Name().SetAssigned(true)
                        if r.Name().IsClosureVar() {
                                r.Name().Defn.Name().SetAssigned(true)
@@ -3279,6 +3331,7 @@ func checkassign(stmt ir.Node, n ir.Node) {
                return
        }
        if n.Op() == ir.OINDEXMAP {
+               n := n.(*ir.IndexExpr)
                n.SetIndexMapLValue(true)
                return
        }
@@ -3529,6 +3582,7 @@ func typecheckas2(n *ir.AssignListStmt) {
                        case ir.ORECV:
                                n.SetOp(ir.OAS2RECV)
                        case ir.ODOTTYPE:
+                               r := r.(*ir.TypeAssertExpr)
                                n.SetOp(ir.OAS2DOTTYPE)
                                r.SetOp(ir.ODOTTYPE2)
                        }
@@ -3554,6 +3608,7 @@ mismatch:
        default:
                base.Errorf("assignment mismatch: %d variables but %d values", cl, cr)
        case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
+               r := r.(*ir.CallExpr)
                base.Errorf("assignment mismatch: %d variables but %v returns %d values", cl, r.Left(), cr)
        }
 
@@ -3768,6 +3823,7 @@ func typecheckdef(n ir.Node) {
                }
 
        case ir.ONAME:
+               n := n.(*ir.Name)
                if n.Name().Ntype != nil {
                        n.Name().Ntype = typecheckNtype(n.Name().Ntype)
                        n.SetType(n.Name().Ntype.Type())
@@ -3888,6 +3944,7 @@ func markBreak(fn *ir.Func) {
                        ir.DoChildren(n, mark)
 
                case ir.OBREAK:
+                       n := n.(*ir.BranchStmt)
                        if n.Sym() == nil {
                                setHasBreak(implicit)
                        } else {
@@ -3980,12 +4037,14 @@ func isTermNode(n ir.Node) bool {
        // skipping over the label. No case OLABEL here.
 
        case ir.OBLOCK:
+               n := n.(*ir.BlockStmt)
                return isTermNodes(n.List())
 
        case ir.OGOTO, ir.ORETURN, ir.ORETJMP, ir.OPANIC, ir.OFALL:
                return true
 
        case ir.OFOR, ir.OFORUNTIL:
+               n := n.(*ir.ForStmt)
                if n.Left() != nil {
                        return false
                }
@@ -3995,9 +4054,11 @@ func isTermNode(n ir.Node) bool {
                return true
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                return isTermNodes(n.Body()) && isTermNodes(n.Rlist())
 
        case ir.OSWITCH:
+               n := n.(*ir.SwitchStmt)
                if n.HasBreak() {
                        return false
                }
@@ -4014,6 +4075,7 @@ func isTermNode(n ir.Node) bool {
                return def
 
        case ir.OSELECT:
+               n := n.(*ir.SelectStmt)
                if n.HasBreak() {
                        return false
                }
@@ -4052,10 +4114,12 @@ func deadcode(fn *ir.Func) {
                }
                switch n.Op() {
                case ir.OIF:
+                       n := n.(*ir.IfStmt)
                        if !ir.IsConst(n.Left(), constant.Bool) || n.Body().Len() > 0 || n.Rlist().Len() > 0 {
                                return
                        }
                case ir.OFOR:
+                       n := n.(*ir.ForStmt)
                        if !ir.IsConst(n.Left(), constant.Bool) || ir.BoolVal(n.Left()) {
                                return
                        }
@@ -4083,6 +4147,7 @@ func deadcodeslice(nn *ir.Nodes) {
                        continue
                }
                if n.Op() == ir.OIF {
+                       n := n.(*ir.IfStmt)
                        n.SetLeft(deadcodeexpr(n.Left()))
                        if ir.IsConst(n.Left(), constant.Bool) {
                                var body ir.Nodes
@@ -4112,19 +4177,26 @@ func deadcodeslice(nn *ir.Nodes) {
                deadcodeslice(n.PtrInit())
                switch n.Op() {
                case ir.OBLOCK:
+                       n := n.(*ir.BlockStmt)
                        deadcodeslice(n.PtrList())
                case ir.OCASE:
+                       n := n.(*ir.CaseStmt)
                        deadcodeslice(n.PtrBody())
                case ir.OFOR:
+                       n := n.(*ir.ForStmt)
                        deadcodeslice(n.PtrBody())
                case ir.OIF:
+                       n := n.(*ir.IfStmt)
                        deadcodeslice(n.PtrBody())
                        deadcodeslice(n.PtrRlist())
                case ir.ORANGE:
+                       n := n.(*ir.RangeStmt)
                        deadcodeslice(n.PtrBody())
                case ir.OSELECT:
+                       n := n.(*ir.SelectStmt)
                        deadcodeslice(n.PtrList())
                case ir.OSWITCH:
+                       n := n.(*ir.SwitchStmt)
                        deadcodeslice(n.PtrList())
                }
 
@@ -4141,6 +4213,7 @@ func deadcodeexpr(n ir.Node) ir.Node {
        // producing a constant 'if' condition.
        switch n.Op() {
        case ir.OANDAND:
+               n := n.(*ir.LogicalExpr)
                n.SetLeft(deadcodeexpr(n.Left()))
                n.SetRight(deadcodeexpr(n.Right()))
                if ir.IsConst(n.Left(), constant.Bool) {
@@ -4151,6 +4224,7 @@ func deadcodeexpr(n ir.Node) ir.Node {
                        }
                }
        case ir.OOROR:
+               n := n.(*ir.LogicalExpr)
                n.SetLeft(deadcodeexpr(n.Left()))
                n.SetRight(deadcodeexpr(n.Right()))
                if ir.IsConst(n.Left(), constant.Bool) {
@@ -4206,6 +4280,7 @@ func methodExprFunc(n ir.Node) *types.Field {
        case ir.OMETHEXPR:
                return n.(*ir.MethodExpr).Method
        case ir.OCALLPART:
+               n := n.(*ir.CallPartExpr)
                return callpartMethod(n)
        }
        base.Fatalf("unexpected node: %v (%v)", n, n.Op())
index 02dd30297554de7d7678ca56a4ea2aada6f60669..eeedea396e0c0e9a8ec500bf7edb35ecd11c0bf8 100644 (file)
@@ -13,6 +13,7 @@ import (
 func evalunsafe(n ir.Node) int64 {
        switch n.Op() {
        case ir.OALIGNOF, ir.OSIZEOF:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(typecheck(n.Left(), ctxExpr))
                n.SetLeft(defaultlit(n.Left(), nil))
                tr := n.Left().Type()
@@ -27,6 +28,7 @@ func evalunsafe(n ir.Node) int64 {
 
        case ir.OOFFSETOF:
                // must be a selector.
+               n := n.(*ir.UnaryExpr)
                if n.Left().Op() != ir.OXDOT {
                        base.Errorf("invalid expression %v", n)
                        return 0
@@ -64,12 +66,14 @@ func evalunsafe(n ir.Node) int64 {
                                // For Offsetof(s.f), s may itself be a pointer,
                                // but accessing f must not otherwise involve
                                // indirection via embedded pointer types.
+                               r := r.(*ir.SelectorExpr)
                                if r.Left() != sbase {
                                        base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left())
                                        return 0
                                }
                                fallthrough
                        case ir.ODOT:
+                               r := r.(*ir.SelectorExpr)
                                v += r.Offset()
                                next = r.Left()
                        default:
index 17269746e64abd3524ef8a8199c5a2480e7191b2..91b7a184cf8ddcd174d900c6ffaacfa8655de9e0 100644 (file)
@@ -127,6 +127,7 @@ func walkstmt(n ir.Node) ir.Node {
        switch n.Op() {
        default:
                if n.Op() == ir.ONAME {
+                       n := n.(*ir.Name)
                        base.Errorf("%v is not a top level statement", n.Sym())
                } else {
                        base.Errorf("%v is not a top level statement", n.Op())
@@ -181,6 +182,7 @@ func walkstmt(n ir.Node) ir.Node {
        // special case for a receive where we throw away
        // the value received.
        case ir.ORECV:
+               n := n.(*ir.UnaryExpr)
                if n.Typecheck() == 0 {
                        base.Fatalf("missing typecheck: %+v", n)
                }
@@ -205,6 +207,7 @@ func walkstmt(n ir.Node) ir.Node {
                return n
 
        case ir.ODCL:
+               n := n.(*ir.Decl)
                v := n.Left().(*ir.Name)
                if v.Class() == ir.PAUTOHEAP {
                        if base.Flag.CompilingRuntime {
@@ -217,6 +220,7 @@ func walkstmt(n ir.Node) ir.Node {
                return n
 
        case ir.OBLOCK:
+               n := n.(*ir.BlockStmt)
                walkstmtlist(n.List().Slice())
                return n
 
@@ -225,6 +229,7 @@ func walkstmt(n ir.Node) ir.Node {
                panic("unreachable")
 
        case ir.ODEFER:
+               n := n.(*ir.GoDeferStmt)
                Curfn.SetHasDefer(true)
                Curfn.NumDefers++
                if Curfn.NumDefers > maxOpenDefers {
@@ -240,6 +245,7 @@ func walkstmt(n ir.Node) ir.Node {
                }
                fallthrough
        case ir.OGO:
+               n := n.(*ir.GoDeferStmt)
                var init ir.Nodes
                switch call := n.Left(); call.Op() {
                case ir.OPRINT, ir.OPRINTN:
@@ -276,6 +282,7 @@ func walkstmt(n ir.Node) ir.Node {
                return n
 
        case ir.OFOR, ir.OFORUNTIL:
+               n := n.(*ir.ForStmt)
                if n.Left() != nil {
                        walkstmtlist(n.Left().Init().Slice())
                        init := n.Left().Init()
@@ -292,12 +299,14 @@ func walkstmt(n ir.Node) ir.Node {
                return n
 
        case ir.OIF:
+               n := n.(*ir.IfStmt)
                n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
                walkstmtlist(n.Body().Slice())
                walkstmtlist(n.Rlist().Slice())
                return n
 
        case ir.ORETURN:
+               n := n.(*ir.ReturnStmt)
                Curfn.NumReturns++
                if n.List().Len() == 0 {
                        return n
@@ -351,9 +360,11 @@ func walkstmt(n ir.Node) ir.Node {
                return n
 
        case ir.ORETJMP:
+               n := n.(*ir.BranchStmt)
                return n
 
        case ir.OINLMARK:
+               n := n.(*ir.InlineMarkStmt)
                return n
 
        case ir.OSELECT:
@@ -489,6 +500,7 @@ func walkexpr(n ir.Node, init *ir.Nodes) ir.Node {
        }
 
        if n.Op() == ir.ONAME && n.(*ir.Name).Class() == ir.PAUTOHEAP {
+               n := n.(*ir.Name)
                nn := ir.NewStarExpr(base.Pos, n.Name().Heapaddr)
                nn.Left().MarkNonNil()
                return walkexpr(typecheck(nn, ctxExpr), init)
@@ -543,22 +555,27 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.ONOT, ir.ONEG, ir.OPLUS, ir.OBITNOT, ir.OREAL, ir.OIMAG, ir.OSPTR, ir.OITAB, ir.OIDATA:
+               n := n.(*ir.UnaryExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                return n
 
        case ir.ODOTMETH, ir.ODOTINTER:
+               n := n.(*ir.SelectorExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                return n
 
        case ir.OADDR:
+               n := n.(*ir.AddrExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                return n
 
        case ir.ODEREF:
+               n := n.(*ir.StarExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                return n
 
        case ir.OEFACE, ir.OAND, ir.OANDNOT, ir.OSUB, ir.OMUL, ir.OADD, ir.OOR, ir.OXOR, ir.OLSH, ir.ORSH:
+               n := n.(*ir.BinaryExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                n.SetRight(walkexpr(n.Right(), init))
                return n
@@ -570,6 +587,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.ODOTTYPE, ir.ODOTTYPE2:
+               n := n.(*ir.TypeAssertExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                // Set up interface type addresses for back end.
                n.SetRight(typename(n.Type()))
@@ -582,6 +600,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.OLEN, ir.OCAP:
+               n := n.(*ir.UnaryExpr)
                if isRuneCount(n) {
                        // Replace len([]rune(string)) with runtime.countrunes(string).
                        return mkcall("countrunes", n.Type(), init, conv(n.Left().(*ir.ConvExpr).Left(), types.Types[types.TSTRING]))
@@ -605,6 +624,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.OCOMPLEX:
+               n := n.(*ir.BinaryExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                n.SetRight(walkexpr(n.Right(), init))
                return n
@@ -614,6 +634,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return walkcompare(n, init)
 
        case ir.OANDAND, ir.OOROR:
+               n := n.(*ir.LogicalExpr)
                n.SetLeft(walkexpr(n.Left(), init))
 
                // cannot put side effects from n.Right on init,
@@ -629,9 +650,11 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return walkprint(n.(*ir.CallExpr), init)
 
        case ir.OPANIC:
+               n := n.(*ir.UnaryExpr)
                return mkcall("gopanic", nil, init, n.Left())
 
        case ir.ORECOVER:
+               n := n.(*ir.CallExpr)
                return mkcall("gorecover", n.Type(), init, nodAddr(nodfp))
 
        case ir.OCLOSUREREAD, ir.OCFUNC:
@@ -674,8 +697,10 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                var left, right ir.Node
                switch n.Op() {
                case ir.OAS:
+                       n := n.(*ir.AssignStmt)
                        left, right = n.Left(), n.Right()
                case ir.OASOP:
+                       n := n.(*ir.AssignOpStmt)
                        left, right = n.Left(), n.Right()
                }
 
@@ -683,6 +708,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                // the mapassign call.
                var mapAppend *ir.CallExpr
                if left.Op() == ir.OINDEXMAP && right.Op() == ir.OAPPEND {
+                       left := left.(*ir.IndexExpr)
                        mapAppend = right.(*ir.CallExpr)
                        if !samesafeexpr(left, mapAppend.List().First()) {
                                base.Fatalf("not same expressions: %v != %v", left, mapAppend.List().First())
@@ -764,6 +790,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return as
 
        case ir.OAS2:
+               n := n.(*ir.AssignListStmt)
                init.AppendNodes(n.PtrInit())
                walkexprlistsafe(n.List().Slice(), init)
                walkexprlistsafe(n.Rlist().Slice(), init)
@@ -771,6 +798,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
 
        // a,b,... = fn()
        case ir.OAS2FUNC:
+               n := n.(*ir.AssignListStmt)
                init.AppendNodes(n.PtrInit())
 
                r := n.Rlist().First()
@@ -789,6 +817,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
        // x, y = <-c
        // order.stmt made sure x is addressable or blank.
        case ir.OAS2RECV:
+               n := n.(*ir.AssignListStmt)
                init.AppendNodes(n.PtrInit())
 
                r := n.Rlist().First().(*ir.UnaryExpr) // recv
@@ -807,6 +836,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
 
        // a,b = m[i]
        case ir.OAS2MAPR:
+               n := n.(*ir.AssignListStmt)
                init.AppendNodes(n.PtrInit())
 
                r := n.Rlist().First().(*ir.IndexExpr)
@@ -868,6 +898,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(as, ctxStmt), init)
 
        case ir.ODELETE:
+               n := n.(*ir.CallExpr)
                init.AppendNodes(n.PtrInit())
                map_ := n.List().First()
                key := n.List().Second()
@@ -883,11 +914,13 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)
 
        case ir.OAS2DOTTYPE:
+               n := n.(*ir.AssignListStmt)
                walkexprlistsafe(n.List().Slice(), init)
                n.PtrRlist().SetIndex(0, walkexpr(n.Rlist().First(), init))
                return n
 
        case ir.OCONVIFACE:
+               n := n.(*ir.ConvExpr)
                n.SetLeft(walkexpr(n.Left(), init))
 
                fromType := n.Left().Type()
@@ -1061,6 +1094,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return conv(mkcall(fn, types.Types[result], init, conv(n.Left(), types.Types[param])), n.Type())
 
        case ir.ODIV, ir.OMOD:
+               n := n.(*ir.BinaryExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                n.SetRight(walkexpr(n.Right(), init))
 
@@ -1120,6 +1154,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return n
 
        case ir.OINDEX:
+               n := n.(*ir.IndexExpr)
                n.SetLeft(walkexpr(n.Left(), init))
 
                // save the original node for bounds checking elision.
@@ -1164,6 +1199,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
 
        case ir.OINDEXMAP:
                // Replace m[k] with *map{access1,assign}(maptype, m, &k)
+               n := n.(*ir.IndexExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                n.SetRight(walkexpr(n.Right(), init))
                map_ := n.Left()
@@ -1207,6 +1243,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                panic("unreachable")
 
        case ir.OSLICEHEADER:
+               n := n.(*ir.SliceHeaderExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                n.List().SetFirst(walkexpr(n.List().First(), init))
                n.List().SetSecond(walkexpr(n.List().Second(), init))
@@ -1251,6 +1288,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return reduceSlice(n)
 
        case ir.ONEW:
+               n := n.(*ir.UnaryExpr)
                if n.Type().Elem().NotInHeap() {
                        base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem())
                }
@@ -1277,6 +1315,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
 
        case ir.OCLOSE:
                // cannot use chanfn - closechan takes any, not chan any
+               n := n.(*ir.UnaryExpr)
                fn := syslook("closechan")
                fn = substArgTypes(fn, n.Left().Type())
                return mkcall1(fn, nil, init, n.Left())
@@ -1284,6 +1323,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
        case ir.OMAKECHAN:
                // When size fits into int, use makechan instead of
                // makechan64, which is faster and shorter on 32 bit platforms.
+               n := n.(*ir.MakeExpr)
                size := n.Left()
                fnname := "makechan64"
                argtype := types.Types[types.TINT64]
@@ -1299,6 +1339,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall1(chanfn(fnname, 1, n.Type()), n.Type(), init, typename(n.Type()), conv(size, argtype))
 
        case ir.OMAKEMAP:
+               n := n.(*ir.MakeExpr)
                t := n.Type()
                hmapType := hmap(t)
                hint := n.Left()
@@ -1400,6 +1441,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall1(fn, n.Type(), init, typename(n.Type()), conv(hint, argtype), h)
 
        case ir.OMAKESLICE:
+               n := n.(*ir.MakeExpr)
                l := n.Left()
                r := n.Right()
                if r == nil {
@@ -1471,6 +1513,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(m, ctxExpr), init)
 
        case ir.OMAKESLICECOPY:
+               n := n.(*ir.MakeExpr)
                if n.Esc() == EscNone {
                        base.Fatalf("OMAKESLICECOPY with EscNone: %v", n)
                }
@@ -1525,6 +1568,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return walkexpr(typecheck(s, ctxExpr), init)
 
        case ir.ORUNESTR:
+               n := n.(*ir.ConvExpr)
                a := nodnil()
                if n.Esc() == EscNone {
                        t := types.NewArray(types.Types[types.TUINT8], 4)
@@ -1534,6 +1578,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall("intstring", n.Type(), init, a, conv(n.Left(), types.Types[types.TINT64]))
 
        case ir.OBYTES2STR, ir.ORUNES2STR:
+               n := n.(*ir.ConvExpr)
                a := nodnil()
                if n.Esc() == EscNone {
                        // Create temporary buffer for string on stack.
@@ -1550,6 +1595,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall("slicebytetostring", n.Type(), init, a, ptr, len)
 
        case ir.OBYTES2STRTMP:
+               n := n.(*ir.ConvExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                if !instrumenting {
                        // Let the backend handle OBYTES2STRTMP directly
@@ -1562,6 +1608,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return mkcall("slicebytetostringtmp", n.Type(), init, ptr, len)
 
        case ir.OSTR2BYTES:
+               n := n.(*ir.ConvExpr)
                s := n.Left()
                if ir.IsConst(s, constant.String) {
                        sc := ir.StringVal(s)
@@ -1607,10 +1654,12 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                // that know that the slice won't be mutated.
                // The only such case today is:
                // for i, c := range []byte(string)
+               n := n.(*ir.ConvExpr)
                n.SetLeft(walkexpr(n.Left(), init))
                return n
 
        case ir.OSTR2RUNES:
+               n := n.(*ir.ConvExpr)
                a := nodnil()
                if n.Esc() == EscNone {
                        // Create temporary buffer for slice on stack.
@@ -1634,6 +1683,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
                return var_
 
        case ir.OSEND:
+               n := n.(*ir.SendStmt)
                n1 := n.Right()
                n1 = assignconv(n1, n.Left().Type().Elem(), "chan send")
                n1 = walkexpr(n1, init)
@@ -2100,8 +2150,10 @@ func isReflectHeaderDataField(l ir.Node) bool {
        var tsym *types.Sym
        switch l.Op() {
        case ir.ODOT:
+               l := l.(*ir.SelectorExpr)
                tsym = l.Left().Type().Sym()
        case ir.ODOTPTR:
+               l := l.(*ir.SelectorExpr)
                tsym = l.Left().Type().Elem().Sym()
        default:
                return false
@@ -2167,12 +2219,15 @@ func reorder3(all []*ir.AssignStmt) []ir.Node {
                for {
                        switch ll := l; ll.Op() {
                        case ir.ODOT:
+                               ll := ll.(*ir.SelectorExpr)
                                l = ll.Left()
                                continue
                        case ir.OPAREN:
+                               ll := ll.(*ir.ParenExpr)
                                l = ll.Left()
                                continue
                        case ir.OINDEX:
+                               ll := ll.(*ir.IndexExpr)
                                if ll.Left().Type().IsArray() {
                                        ll.SetRight(reorder3save(ll.Right(), all, i, &early))
                                        l = ll.Left()
@@ -2190,6 +2245,7 @@ func reorder3(all []*ir.AssignStmt) []ir.Node {
                        break
 
                case ir.OINDEX, ir.OINDEXMAP:
+                       l := l.(*ir.IndexExpr)
                        l.SetLeft(reorder3save(l.Left(), all, i, &early))
                        l.SetRight(reorder3save(l.Right(), all, i, &early))
                        if l.Op() == ir.OINDEXMAP {
@@ -2197,8 +2253,10 @@ func reorder3(all []*ir.AssignStmt) []ir.Node {
                        }
 
                case ir.ODEREF:
+                       l := l.(*ir.StarExpr)
                        l.SetLeft(reorder3save(l.Left(), all, i, &early))
                case ir.ODOTPTR:
+                       l := l.(*ir.SelectorExpr)
                        l.SetLeft(reorder3save(l.Left(), all, i, &early))
                }
 
@@ -2238,15 +2296,19 @@ func outervalue(n ir.Node) ir.Node {
                case ir.OXDOT:
                        base.Fatalf("OXDOT in walk")
                case ir.ODOT:
+                       nn := nn.(*ir.SelectorExpr)
                        n = nn.Left()
                        continue
                case ir.OPAREN:
+                       nn := nn.(*ir.ParenExpr)
                        n = nn.Left()
                        continue
                case ir.OCONVNOP:
+                       nn := nn.(*ir.ConvExpr)
                        n = nn.Left()
                        continue
                case ir.OINDEX:
+                       nn := nn.(*ir.IndexExpr)
                        if nn.Left().Type() != nil && nn.Left().Type().IsArray() {
                                n = nn.Left()
                                continue
@@ -2338,6 +2400,7 @@ func anyAddrTaken(n ir.Node) bool {
        return ir.Any(n, func(n ir.Node) bool {
                switch n.Op() {
                case ir.ONAME:
+                       n := n.(*ir.Name)
                        return n.Class() == ir.PEXTERN || n.Class() == ir.PAUTOHEAP || n.Name().Addrtaken()
 
                case ir.ODOT: // but not ODOTPTR - should have been handled in aliased.
@@ -2420,6 +2483,7 @@ func refersToCommonName(l ir.Node, r ir.Node) bool {
        }
        doL = func(l ir.Node) error {
                if l.Op() == ir.ONAME {
+                       l := l.(*ir.Name)
                        targetL = l.Name()
                        if doR(r) == stop {
                                return stop
@@ -3635,6 +3699,7 @@ func bounded(n ir.Node, max int64) bool {
 
        switch n.Op() {
        case ir.OAND, ir.OANDNOT:
+               n := n.(*ir.BinaryExpr)
                v := int64(-1)
                switch {
                case smallintconst(n.Left()):
@@ -3653,6 +3718,7 @@ func bounded(n ir.Node, max int64) bool {
                }
 
        case ir.OMOD:
+               n := n.(*ir.BinaryExpr)
                if !sign && smallintconst(n.Right()) {
                        v := ir.Int64Val(n.Right())
                        if 0 <= v && v <= max {
@@ -3661,6 +3727,7 @@ func bounded(n ir.Node, max int64) bool {
                }
 
        case ir.ODIV:
+               n := n.(*ir.BinaryExpr)
                if !sign && smallintconst(n.Right()) {
                        v := ir.Int64Val(n.Right())
                        for bits > 0 && v >= 2 {
@@ -3670,6 +3737,7 @@ func bounded(n ir.Node, max int64) bool {
                }
 
        case ir.ORSH:
+               n := n.(*ir.BinaryExpr)
                if !sign && smallintconst(n.Right()) {
                        v := ir.Int64Val(n.Right())
                        if v > int64(bits) {
@@ -3849,6 +3917,7 @@ func anySideEffects(n ir.Node) bool {
 
                // Only possible side effect is division by zero.
                case ir.ODIV, ir.OMOD:
+                       n := n.(*ir.BinaryExpr)
                        if n.Right().Op() != ir.OLITERAL || constant.Sign(n.Right().Val()) == 0 {
                                return true
                        }
@@ -3856,6 +3925,7 @@ func anySideEffects(n ir.Node) bool {
                // Only possible side effect is panic on invalid size,
                // but many makechan and makemap use size zero, which is definitely OK.
                case ir.OMAKECHAN, ir.OMAKEMAP:
+                       n := n.(*ir.MakeExpr)
                        if !ir.IsConst(n.Left(), constant.Int) || constant.Sign(n.Left().Val()) != 0 {
                                return true
                        }
@@ -3901,6 +3971,7 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
        if !isBuiltinCall && n.IsDDD() {
                last := n.List().Len() - 1
                if va := n.List().Index(last); va.Op() == ir.OSLICELIT {
+                       va := va.(*ir.CompLitExpr)
                        n.PtrList().Set(append(n.List().Slice()[:last], va.List().Slice()...))
                        n.SetIsDDD(false)
                }
@@ -4051,11 +4122,14 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
        walk = func(n ir.Node) {
                switch n.Op() {
                case ir.OADD:
+                       n := n.(*ir.BinaryExpr)
                        walk(n.Left())
                        walk(n.Right())
                case ir.OSUB, ir.OANDNOT:
+                       n := n.(*ir.BinaryExpr)
                        walk(n.Left())
                case ir.OCONVNOP:
+                       n := n.(*ir.ConvExpr)
                        if n.Left().Type().IsUnsafePtr() {
                                n.SetLeft(cheapexpr(n.Left(), init))
                                originals = append(originals, convnop(n.Left(), types.Types[types.TUNSAFEPTR]))
index 7a945c369029e5d1e6ae29731032fdebc2aed001..53a63afe9b6d97fcb52723c242203030f1ae35e6 100644 (file)
@@ -35,11 +35,6 @@ type miniNode struct {
        esc  uint16
 }
 
-func (n *miniNode) Format(s fmt.State, verb rune)        { panic(1) }
-func (n *miniNode) copy() Node                           { panic(1) }
-func (n *miniNode) doChildren(do func(Node) error) error { panic(1) }
-func (n *miniNode) editChildren(edit func(Node) Node)    { panic(1) }
-
 // posOr returns pos if known, or else n.pos.
 // For use in DeepCopy.
 func (n *miniNode) posOr(pos src.XPos) src.XPos {
@@ -85,106 +80,27 @@ func (n *miniNode) SetDiag(x bool) { n.bits.set(miniDiag, x) }
 
 // Empty, immutable graph structure.
 
-func (n *miniNode) Left() Node       { return nil }
-func (n *miniNode) Right() Node      { return nil }
-func (n *miniNode) Init() Nodes      { return Nodes{} }
-func (n *miniNode) PtrInit() *Nodes  { return &immutableEmptyNodes }
-func (n *miniNode) Body() Nodes      { return Nodes{} }
-func (n *miniNode) PtrBody() *Nodes  { return &immutableEmptyNodes }
-func (n *miniNode) List() Nodes      { return Nodes{} }
-func (n *miniNode) PtrList() *Nodes  { return &immutableEmptyNodes }
-func (n *miniNode) Rlist() Nodes     { return Nodes{} }
-func (n *miniNode) PtrRlist() *Nodes { return &immutableEmptyNodes }
-func (n *miniNode) SetLeft(x Node) {
-       if x != nil {
-               panic(n.no("SetLeft"))
-       }
-}
-func (n *miniNode) SetRight(x Node) {
-       if x != nil {
-               panic(n.no("SetRight"))
-       }
-}
+func (n *miniNode) Init() Nodes     { return Nodes{} }
+func (n *miniNode) PtrInit() *Nodes { return &immutableEmptyNodes }
 func (n *miniNode) SetInit(x Nodes) {
        if x != nil {
                panic(n.no("SetInit"))
        }
 }
-func (n *miniNode) SetBody(x Nodes) {
-       if x != nil {
-               panic(n.no("SetBody"))
-       }
-}
-func (n *miniNode) SetList(x Nodes) {
-       if x != nil {
-               panic(n.no("SetList"))
-       }
-}
-func (n *miniNode) SetRlist(x Nodes) {
-       if x != nil {
-               panic(n.no("SetRlist"))
-       }
-}
 
 // Additional functionality unavailable.
 
 func (n *miniNode) no(name string) string { return "cannot " + name + " on " + n.op.String() }
 
-func (n *miniNode) SetOp(Op)            { panic(n.no("SetOp")) }
-func (n *miniNode) SubOp() Op           { panic(n.no("SubOp")) }
-func (n *miniNode) SetSubOp(Op)         { panic(n.no("SetSubOp")) }
-func (n *miniNode) Type() *types.Type   { return nil }
-func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) }
-func (n *miniNode) Func() *Func         { return nil }
-func (n *miniNode) Name() *Name         { return nil }
-func (n *miniNode) Sym() *types.Sym     { return nil }
-func (n *miniNode) SetSym(*types.Sym)   { panic(n.no("SetSym")) }
-func (n *miniNode) Offset() int64       { return types.BADWIDTH }
-func (n *miniNode) SetOffset(x int64)   { panic(n.no("SetOffset")) }
-func (n *miniNode) Class() Class        { return Pxxx }
-func (n *miniNode) SetClass(Class)      { panic(n.no("SetClass")) }
-func (n *miniNode) Likely() bool        { panic(n.no("Likely")) }
-func (n *miniNode) SetLikely(bool)      { panic(n.no("SetLikely")) }
-func (n *miniNode) SliceBounds() (low, high, max Node) {
-       panic(n.no("SliceBounds"))
-}
-func (n *miniNode) SetSliceBounds(low, high, max Node) {
-       panic(n.no("SetSliceBounds"))
-}
-func (n *miniNode) Iota() int64               { panic(n.no("Iota")) }
-func (n *miniNode) SetIota(int64)             { panic(n.no("SetIota")) }
-func (n *miniNode) Colas() bool               { return false }
-func (n *miniNode) SetColas(bool)             { panic(n.no("SetColas")) }
-func (n *miniNode) NoInline() bool            { panic(n.no("NoInline")) }
-func (n *miniNode) SetNoInline(bool)          { panic(n.no("SetNoInline")) }
-func (n *miniNode) Transient() bool           { panic(n.no("Transient")) }
-func (n *miniNode) SetTransient(bool)         { panic(n.no("SetTransient")) }
-func (n *miniNode) Implicit() bool            { return false }
-func (n *miniNode) SetImplicit(bool)          { panic(n.no("SetImplicit")) }
-func (n *miniNode) IsDDD() bool               { return false }
-func (n *miniNode) SetIsDDD(bool)             { panic(n.no("SetIsDDD")) }
-func (n *miniNode) Embedded() bool            { return false }
-func (n *miniNode) SetEmbedded(bool)          { panic(n.no("SetEmbedded")) }
-func (n *miniNode) IndexMapLValue() bool      { panic(n.no("IndexMapLValue")) }
-func (n *miniNode) SetIndexMapLValue(bool)    { panic(n.no("SetIndexMapLValue")) }
-func (n *miniNode) ResetAux()                 { panic(n.no("ResetAux")) }
-func (n *miniNode) HasBreak() bool            { panic(n.no("HasBreak")) }
-func (n *miniNode) SetHasBreak(bool)          { panic(n.no("SetHasBreak")) }
-func (n *miniNode) Val() constant.Value       { panic(n.no("Val")) }
-func (n *miniNode) SetVal(v constant.Value)   { panic(n.no("SetVal")) }
-func (n *miniNode) Int64Val() int64           { panic(n.no("Int64Val")) }
-func (n *miniNode) Uint64Val() uint64         { panic(n.no("Uint64Val")) }
-func (n *miniNode) CanInt64() bool            { panic(n.no("CanInt64")) }
-func (n *miniNode) BoolVal() bool             { panic(n.no("BoolVal")) }
-func (n *miniNode) StringVal() string         { panic(n.no("StringVal")) }
-func (n *miniNode) HasCall() bool             { return false }
-func (n *miniNode) SetHasCall(bool)           { panic(n.no("SetHasCall")) }
-func (n *miniNode) NonNil() bool              { return false }
-func (n *miniNode) MarkNonNil()               { panic(n.no("MarkNonNil")) }
-func (n *miniNode) Bounded() bool             { return false }
-func (n *miniNode) SetBounded(bool)           { panic(n.no("SetBounded")) }
-func (n *miniNode) Opt() interface{}          { return nil }
-func (n *miniNode) SetOpt(interface{})        { panic(n.no("SetOpt")) }
-func (n *miniNode) MarkReadonly()             { panic(n.no("MarkReadonly")) }
-func (n *miniNode) TChanDir() types.ChanDir   { panic(n.no("TChanDir")) }
-func (n *miniNode) SetTChanDir(types.ChanDir) { panic(n.no("SetTChanDir")) }
+func (n *miniNode) Type() *types.Type       { return nil }
+func (n *miniNode) SetType(*types.Type)     { panic(n.no("SetType")) }
+func (n *miniNode) Name() *Name             { return nil }
+func (n *miniNode) Sym() *types.Sym         { return nil }
+func (n *miniNode) Val() constant.Value     { panic(n.no("Val")) }
+func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) }
+func (n *miniNode) HasCall() bool           { return false }
+func (n *miniNode) SetHasCall(bool)         { panic(n.no("SetHasCall")) }
+func (n *miniNode) NonNil() bool            { return false }
+func (n *miniNode) MarkNonNil()             { panic(n.no("MarkNonNil")) }
+func (n *miniNode) Opt() interface{}        { return nil }
+func (n *miniNode) SetOpt(interface{})      { panic(n.no("SetOpt")) }
index 1679313c862905a0905214b6051de2df0a3096b9..86ef600f266ad05468c4f21c6cd46a6aa3c49ea7 100644 (file)
@@ -33,59 +33,15 @@ type Node interface {
 
        // Abstract graph structure, for generic traversals.
        Op() Op
-       SetOp(x Op)
-       SubOp() Op
-       SetSubOp(x Op)
-       Left() Node
-       SetLeft(x Node)
-       Right() Node
-       SetRight(x Node)
        Init() Nodes
        PtrInit() *Nodes
        SetInit(x Nodes)
-       Body() Nodes
-       PtrBody() *Nodes
-       SetBody(x Nodes)
-       List() Nodes
-       SetList(x Nodes)
-       PtrList() *Nodes
-       Rlist() Nodes
-       SetRlist(x Nodes)
-       PtrRlist() *Nodes
 
        // Fields specific to certain Ops only.
        Type() *types.Type
        SetType(t *types.Type)
-       Func() *Func
        Name() *Name
        Sym() *types.Sym
-       SetSym(x *types.Sym)
-       Offset() int64
-       SetOffset(x int64)
-       Class() Class
-       SetClass(x Class)
-       Likely() bool
-       SetLikely(x bool)
-       SliceBounds() (low, high, max Node)
-       SetSliceBounds(low, high, max Node)
-       Iota() int64
-       SetIota(x int64)
-       Colas() bool
-       SetColas(x bool)
-       NoInline() bool
-       SetNoInline(x bool)
-       Transient() bool
-       SetTransient(x bool)
-       Implicit() bool
-       SetImplicit(x bool)
-       IsDDD() bool
-       SetIsDDD(x bool)
-       IndexMapLValue() bool
-       SetIndexMapLValue(x bool)
-       ResetAux()
-       HasBreak() bool
-       SetHasBreak(x bool)
-       MarkReadonly()
        Val() constant.Value
        SetVal(v constant.Value)
 
@@ -98,8 +54,6 @@ type Node interface {
        SetOpt(x interface{})
        Diag() bool
        SetDiag(x bool)
-       Bounded() bool
-       SetBounded(x bool)
        Typecheck() uint8
        SetTypecheck(x uint8)
        NonNil() bool