diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index d8a30e11f1..601154b346 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -72,7 +72,7 @@ func closurebody(body *NodeList) *Node { var v *Node for l := func_.Func.Cvars; l != nil; l = l.Next { v = l.N - v.Name.Param.Closure.Name.Closure = v.Name.Outer + v.Name.Param.Closure.Name.Param.Closure = v.Name.Param.Outer v.Name.Param.Outerexpr = oldname(v.Sym) } diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index e9ac674952..94afd00d0d 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -411,7 +411,7 @@ type EscState struct { walkgen uint32 } -// funcSym returns n.Nname.Sym if no nils are encountered along the way. +// funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way. func funcSym(fn *Node) *Sym { if fn == nil || fn.Func.Nname == nil { return nil @@ -1238,7 +1238,14 @@ func escassignfromtag(e *EscState, note *string, dsts *NodeList, src *Node) uint return em0 } -// e.addDereference constructs a suitable OIND note applied to src. +func escassignDereference(e *EscState, dst *Node, src *Node) { + if src.Op == OLITERAL { + return + } + escassign(e, dst, e.addDereference(src)) +} + +// addDereference constructs a suitable OIND note applied to src. // Because this is for purposes of escape accounting, not execution, // some semantically dubious node combinations are (currently) possible. func (e *EscState) addDereference(n *Node) *Node { diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index f9a35cd3b3..39814e9a88 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -236,6 +236,9 @@ func Jconv(n *Node, flag int) string { if n.Name != nil && n.Name.Funcdepth != 0 { fmt.Fprintf(&buf, " f(%d)", n.Name.Funcdepth) } + if n.Func != nil && n.Func.Depth != 0 { + fmt.Fprintf(&buf, " ff(%d)", n.Func.Depth) + } switch n.Esc { case EscUnknown: diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index 21a8a68b39..024810e0b8 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -98,6 +98,9 @@ type NilVal struct{} func (v Val) Ctype() int { switch x := v.U.(type) { default: + Fatal("unexpected Ctype for %T", v.U) + panic("not reached") + case nil: return 0 case *NilVal: return CTNIL diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index c00e3c1d76..abba42c382 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -18,9 +18,11 @@ const ( InitPending = 2 ) -var initlist *NodeList -var initplans = make(map[*Node]*InitPlan) -var inittemps = make(map[*Node]*Node) +var ( + initlist *NodeList + initplans map[*Node]*InitPlan + inittemps = make(map[*Node]*Node) +) // init1 walks the AST starting at n, and accumulates in out // the list of definitions needing init code in dependency order. @@ -255,9 +257,11 @@ func initreorder(l *NodeList, out **NodeList) { // to include in the init() function body. func initfix(l *NodeList) *NodeList { var lout *NodeList + initplans = make(map[*Node]*InitPlan) lno := int(lineno) initreorder(l, &lout) lineno = int32(lno) + initplans = nil return lout } diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 627b86d046..2ac2fec0c5 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -333,6 +333,7 @@ func importdot(opkg *Pkg, pack *Node) { s1.Block = s.Block if s1.Def.Name == nil { Dump("s1def", s1.Def) + Fatal("missing Name") } s1.Def.Name.Pack = pack s1.Origpkg = opkg diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 436193fa92..c645c35035 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -280,7 +280,6 @@ func (s *exprSwitch) walk(sw *Node) { sw.Nbody = concat(cas, sw.Nbody) walkstmtlist(sw.Nbody) } - } // walkCases generates an AST implementing the cases in cc. diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index f76bb392b6..773de8bb70 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -73,15 +73,15 @@ type Node struct { // Name holds Node fields used only by named nodes (ONAME, OPACK, some OLITERAL). type Name struct { - Pack *Node // real package for import . names - Pkg *Pkg // pkg for OPACK nodes - Heapaddr *Node // temp holding heap address of param - Inlvar *Node // ONAME substitute while inlining - Defn *Node // initializing assignment - Curfn *Node // function for local variables - *Param + Pack *Node // real package for import . names + Pkg *Pkg // pkg for OPACK nodes + Heapaddr *Node // temp holding heap address of param + Inlvar *Node // ONAME substitute while inlining + Defn *Node // initializing assignment + Curfn *Node // function for local variables + Param *Param Decldepth int32 // declaration loop depth, increased for every loop or label - Vargen int32 // unique name for OTYPE/ONAME within a function. Function outputs are numbered starting at one. + Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. Iota int32 // value if this name is iota Funcdepth int32 Method bool // OCALLMETH name diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index fbbae4d508..a68b7d3d93 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -823,7 +823,7 @@ OpSwitch: } l.Addrtaken = true if l.Name != nil && l.Name.Param != nil && l.Name.Param.Closure != nil { - l.Name.Closure.Addrtaken = true + l.Name.Param.Closure.Addrtaken = true } defaultlit(&n.Left, nil) l = n.Left @@ -2832,36 +2832,36 @@ func keydup(n *Node, hash map[uint32][]*Node) { return // we dont check variables } - var b uint32 + var h uint32 switch n.Val.Ctype() { default: // unknown, bool, nil - b = 23 + h = 23 case CTINT, CTRUNE: - b = uint32(Mpgetfix(n.Val.U.(*Mpint))) + h = uint32(Mpgetfix(n.Val.U.(*Mpint))) case CTFLT: d := mpgetflt(n.Val.U.(*Mpflt)) x := math.Float64bits(d) for i := 0; i < 8; i++ { - b = b*PRIME1 + uint32(x&0xFF) + h = h*PRIME1 + uint32(x&0xFF) x >>= 8 } case CTSTR: - b = 0 + h = 0 s := n.Val.U.(string) for i := len(n.Val.U.(string)); i > 0; i-- { - b = b*PRIME1 + uint32(s[0]) + h = h*PRIME1 + uint32(s[0]) s = s[1:] } } var cmp Node - for _, a := range hash[b] { + for _, a := range hash[h] { cmp.Op = OEQ cmp.Left = n - b = 0 + b := uint32(0) if a.Op == OCONVIFACE && orign.Op == OCONVIFACE { if Eqtype(a.Left.Type, n.Type) { cmp.Right = a.Left @@ -2880,7 +2880,7 @@ func keydup(n *Node, hash map[uint32][]*Node) { } } - hash[b] = append(hash[b], orign) + hash[h] = append(hash[h], orign) } func indexdup(n *Node, hash map[int64]*Node) { @@ -3936,7 +3936,7 @@ func markbreaklist(l *NodeList, implicit *Node) { lab = new(Label) lab.Def = n.Name.Defn n.Left.Sym.Label = lab - markbreak(n.Name.Defn, n.Name.Defn) // XXX + markbreak(n.Name.Defn, n.Name.Defn) n.Left.Sym.Label = nil l = l.Next continue