]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: clear OTFUNC info when converting to OTYPE
authorIan Lance Taylor <iant@golang.org>
Mon, 28 Mar 2016 02:44:06 +0000 (19:44 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 28 Mar 2016 14:10:21 +0000 (14:10 +0000)
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 <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/typecheck.go

index 20e03f5cd9d22fcf212fc4546fececdb22a19a15..99336694fe3672ee3c2f3a859037493b2b48e185 100644 (file)
@@ -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
index ee7c34c8956ed20f82a75f970cc25af4cf03c787..cd6aabfd235bc4ca895a9d277b2ea1c87c000e86 100644 (file)
@@ -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: