From: Ian Lance Taylor Date: Mon, 28 Mar 2016 02:44:06 +0000 (-0700) Subject: cmd/compile: clear OTFUNC info when converting to OTYPE X-Git-Tag: go1.7beta1~1068 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7e88826a69366bbcb64f2f89dbe02c57f7ebf678;p=gostls13.git cmd/compile: clear OTFUNC info when converting to OTYPE I want to get rid of OTFUNC, which serves no useful purpose. However, it turns out that the escape analysis pass looks at the node slices set up for OTFUNC, even though by the time escape analysis runs the OTFUNC has been converted to OTYPE. This CL converts the escape analysis code to look at the function decls instead, and clears the OTFUNC info when converting to OTYPE to ensure that nothing else looks at it. Change-Id: I3f2f5997ea8ea7a127a858e94b20aabfab84a5bf Reviewed-on: https://go-review.googlesource.com/21202 Run-TryBot: Ian Lance Taylor Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 20e03f5cd9..99336694fe 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -1474,48 +1474,51 @@ func esccall(e *EscState, n *Node, up *Node) { if fn.Name.Defn.Esc == EscFuncUnknown || nE.Escretval.Len() != 0 { Fatalf("graph inconsistency") } - // set up out list on this call node - for _, n2 := range fn.Name.Param.Ntype.Rlist.Slice() { - nE.Escretval.Append(n2.Left) // type.rlist -> dclfield -> ONAME (PPARAMOUT) - } - - // Receiver. - if n.Op != OCALLFUNC { - escassignNilWhy(e, fn.Name.Param.Ntype.Left.Left, n.Left.Left, "call receiver") - } - var src *Node lls := ll.Slice() - lrs := fn.Name.Param.Ntype.List.Slice() - i := 0 - for ; i < len(lls) && i < len(lrs); i++ { - src = lls[i] - if lrs[i].Isddd && !n.Isddd { - // Introduce ODDDARG node to represent ... allocation. - src = Nod(ODDDARG, nil, nil) - src.Type = typ(TARRAY) - src.Type.Type = lrs[i].Type.Type - src.Type.Bound = int64(len(lls) - i) - src.Type = Ptrto(src.Type) // make pointer so it will be tracked - src.Lineno = n.Lineno - e.track(src) - n.Right = src - } + sawRcvr := false + var src *Node + DclLoop: + for _, n2 := range fn.Name.Defn.Func.Dcl { + switch n2.Class { + case PPARAM: + if n.Op != OCALLFUNC && !sawRcvr { + escassignNilWhy(e, n2, n.Left.Left, "call receiver") + sawRcvr = true + continue DclLoop + } + if len(lls) == 0 { + continue DclLoop + } + src = lls[0] + if n2.Isddd && !n.Isddd { + // Introduce ODDDARG node to represent ... allocation. + src = Nod(ODDDARG, nil, nil) + src.Type = typ(TARRAY) + src.Type.Type = n2.Type.Type + src.Type.Bound = int64(len(lls)) + src.Type = Ptrto(src.Type) // make pointer so it will be tracked + src.Lineno = n.Lineno + e.track(src) + n.Right = src + } + escassignNilWhy(e, n2, src, "arg to recursive call") + if src != lls[0] { + break DclLoop + } + lls = lls[1:] - if lrs[i].Left != nil { - escassignNilWhy(e, lrs[i].Left, src, "arg to recursive call") - } - if src != lls[i] { - break + case PPARAMOUT: + nE.Escretval.Append(n2) } } // "..." arguments are untracked - for ; i < len(lls); i++ { + for _, n2 := range lls { if Debug['m'] > 3 { - fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(lls[i], FmtShort)) + fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(n2, FmtShort)) } - escassignSinkNilWhy(e, src, lls[i], "... arg to recursive call") + escassignSinkNilWhy(e, src, n2, "... arg to recursive call") } return diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index ee7c34c895..cd6aabfd23 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -448,6 +448,9 @@ OpSwitch: n.Type = nil return n } + n.Left = nil + n.List.Set(nil) + n.Rlist.Set(nil) // type or expr case OIND: