From: Russ Cox Date: Wed, 23 Dec 2020 04:56:32 +0000 (-0500) Subject: [dev.regabi] cmd/compile: remove Node.Left etc [generated] X-Git-Tag: go1.17beta1~1539^2~262 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=14d667341f;p=gostls13.git [dev.regabi] cmd/compile: remove Node.Left etc [generated] 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 Run-TryBot: Russ Cox TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index f8e60ea0a3..e54cd0a102 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -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() } diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 3cfb24f2fc..d85f10faf3 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -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) diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go index c03445044d..0f7d62c5bf 100644 --- a/src/cmd/compile/internal/gc/iexport.go +++ b/src/cmd/compile/internal/gc/iexport.go @@ -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 = " initializing statements, hope they're always // preceded by the DCL which will be re-parsed and typecheck to reproduce // the "v = " 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()) diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 1148d329a3..40f76cae7b 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -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 diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go index c9c3361d3c..f99c6dd72c 100644 --- a/src/cmd/compile/internal/gc/initorder.go +++ b/src/cmd/compile/internal/gc/initorder.go @@ -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() } diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 122c19f6df..7cb7946806 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -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) } diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index d2d908bf9f..4b7a22e654 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -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) diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index 2e7838c252..96164d09fd 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -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 diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/gc/scc.go index 8fe20a80fd..f2d089fa4c 100644 --- a/src/cmd/compile/internal/gc/scc.go +++ b/src/cmd/compile/internal/gc/scc.go @@ -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 { diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go index be2f688eb9..64d3461dca 100644 --- a/src/cmd/compile/internal/gc/select.go +++ b/src/cmd/compile/internal/gc/select.go @@ -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)) diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index 5a96d4c320..f4988df9ac 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -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()) { diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index cc5f9eeea6..dc3ea4be9e 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -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()) } diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 174452def2..5aebae0b18 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -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 } diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 1866a6a784..7cd1c16e00 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -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) } diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index db03fd9e75..bb5e9fad1e 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -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()) diff --git a/src/cmd/compile/internal/gc/unsafe.go b/src/cmd/compile/internal/gc/unsafe.go index 02dd302975..eeedea396e 100644 --- a/src/cmd/compile/internal/gc/unsafe.go +++ b/src/cmd/compile/internal/gc/unsafe.go @@ -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: diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 17269746e6..91b7a184cf 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -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])) diff --git a/src/cmd/compile/internal/ir/mini.go b/src/cmd/compile/internal/ir/mini.go index 7a945c3690..53a63afe9b 100644 --- a/src/cmd/compile/internal/ir/mini.go +++ b/src/cmd/compile/internal/ir/mini.go @@ -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")) } diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go index 1679313c86..86ef600f26 100644 --- a/src/cmd/compile/internal/ir/node.go +++ b/src/cmd/compile/internal/ir/node.go @@ -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