]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/gc: remove a bunch of uses of iterField
authorMatthew Dempsky <mdempsky@google.com>
Thu, 6 Apr 2017 02:38:21 +0000 (19:38 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 6 Apr 2017 23:08:54 +0000 (23:08 +0000)
Passes toolstash-check -all.

Change-Id: I9fb91dd78dff149b5e1e1329d00855fd41f12523
Reviewed-on: https://go-review.googlesource.com/39796
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/order.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go

index e97b06c8e5d2064af340a0329ca8c4cd6bb56cf0..272c83d9d55ea53655ea635fdb91ab46e9fdefb6 100644 (file)
@@ -1608,72 +1608,59 @@ func (e *EscState) esccall(call *Node, parent *Node) {
                }
        }
 
-       var arg *Node
-       var note string
-       param, it := iterFields(fntype.Params())
-       i := 0
-       for ; i < len(args); i++ {
-               arg = args[i]
-               note = param.Note
+       for i, param := range fntype.Params().FieldSlice() {
+               note := param.Note
+               var arg *Node
                if param.Isddd() && !call.Isddd() {
+                       rest := args[i:]
+                       if len(rest) == 0 {
+                               break
+                       }
+
                        // Introduce ODDDARG node to represent ... allocation.
                        arg = nod(ODDDARG, nil, nil)
                        arg.Pos = call.Pos
-                       arr := typArray(param.Type.Elem(), int64(len(args)-i))
+                       arr := typArray(param.Type.Elem(), int64(len(rest)))
                        arg.Type = typPtr(arr) // make pointer so it will be tracked
                        e.track(arg)
                        call.Right = arg
-               }
 
-               if haspointers(param.Type) {
-                       if e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC {
-                               a := arg
-                               for a.Op == OCONVNOP {
-                                       a = a.Left
+                       // Store arguments into slice for ... arg.
+                       for _, a := range rest {
+                               if Debug['m'] > 3 {
+                                       fmt.Printf("%v::esccall:: ... <- %S\n", linestr(lineno), a)
                                }
-                               switch a.Op {
-                               // The callee has already been analyzed, so its arguments have esc tags.
-                               // The argument is marked as not escaping at all.
-                               // Record that fact so that any temporary used for
-                               // synthesizing this expression can be reclaimed when
-                               // the function returns.
-                               // This 'noescape' is even stronger than the usual esc == EscNone.
-                               // arg.Esc == EscNone means that arg does not escape the current function.
-                               // arg.SetNoescape(true) here means that arg does not escape this statement
-                               // in the current function.
-                               case OCALLPART,
-                                       OCLOSURE,
-                                       ODDDARG,
-                                       OARRAYLIT,
-                                       OSLICELIT,
-                                       OPTRLIT,
-                                       OSTRUCTLIT:
-                                       a.SetNoescape(true)
+                               if note == uintptrEscapesTag {
+                                       e.escassignSinkWhyWhere(arg, a, "arg to uintptrescapes ...", call)
+                               } else {
+                                       e.escassignWhyWhere(arg, a, "arg to ...", call)
                                }
                        }
+               } else {
+                       arg = args[i]
+                       if note == uintptrEscapesTag {
+                               e.escassignSinkWhy(arg, arg, "escaping uintptr")
+                       }
                }
 
-               if arg != args[i] {
-                       // This occurs when function parameter field Isddd and call not Isddd
-                       break
-               }
-
-               if note == uintptrEscapesTag {
-                       e.escassignSinkWhy(arg, arg, "escaping uintptr")
-               }
-
-               param = it.Next()
-       }
-
-       // Store arguments into slice for ... arg.
-       for ; i < len(args); i++ {
-               if Debug['m'] > 3 {
-                       fmt.Printf("%v::esccall:: ... <- %S\n", linestr(lineno), args[i])
-               }
-               if note == uintptrEscapesTag {
-                       e.escassignSinkWhyWhere(arg, args[i], "arg to uintptrescapes ...", call)
-               } else {
-                       e.escassignWhyWhere(arg, args[i], "arg to ...", call)
+               if haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC {
+                       a := arg
+                       for a.Op == OCONVNOP {
+                               a = a.Left
+                       }
+                       switch a.Op {
+                       // The callee has already been analyzed, so its arguments have esc tags.
+                       // The argument is marked as not escaping at all.
+                       // Record that fact so that any temporary used for
+                       // synthesizing this expression can be reclaimed when
+                       // the function returns.
+                       // This 'noescape' is even stronger than the usual esc == EscNone.
+                       // arg.Esc == EscNone means that arg does not escape the current function.
+                       // arg.SetNoescape(true) here means that arg does not escape this statement
+                       // in the current function.
+                       case OCALLPART, OCLOSURE, ODDDARG, OARRAYLIT, OSLICELIT, OPTRLIT, OSTRUCTLIT:
+                               a.SetNoescape(true)
+                       }
                }
        }
 }
index c4c7a9d76517708c61bd49b7ef95734f355f5045..c3e6d59700243c163122fd45dbf210f175cd3d48 100644 (file)
@@ -390,33 +390,36 @@ func ordercall(n *Node, order *Order) {
        ordercallargs(&n.List, order)
 
        if n.Op == OCALLFUNC {
-               t, it := iterFields(n.Left.Type.Params())
-               for i := range n.List.Slice() {
-                       // Check for "unsafe-uintptr" tag provided by escape analysis.
-                       // If present and the argument is really a pointer being converted
-                       // to uintptr, arrange for the pointer to be kept alive until the call
-                       // returns, by copying it into a temp and marking that temp
+               keepAlive := func(i int) {
+                       // If the argument is really a pointer being converted to uintptr,
+                       // arrange for the pointer to be kept alive until the call returns,
+                       // by copying it into a temp and marking that temp
                        // still alive when we pop the temp stack.
-                       if t == nil {
-                               break
+                       xp := n.List.Addr(i)
+                       for (*xp).Op == OCONVNOP && !(*xp).Type.IsPtr() {
+                               xp = &(*xp).Left
                        }
-                       if t.Note == unsafeUintptrTag || t.Note == uintptrEscapesTag {
-                               xp := n.List.Addr(i)
-                               for (*xp).Op == OCONVNOP && !(*xp).Type.IsPtr() {
-                                       xp = &(*xp).Left
+                       x := *xp
+                       if x.Type.IsPtr() {
+                               x = ordercopyexpr(x, x.Type, order, 0)
+                               x.Name.SetKeepalive(true)
+                               *xp = x
+                       }
+               }
+
+               for i, t := range n.Left.Type.Params().FieldSlice() {
+                       // Check for "unsafe-uintptr" tag provided by escape analysis.
+                       if t.Isddd() && !n.Isddd() {
+                               if t.Note == uintptrEscapesTag {
+                                       for ; i < n.List.Len(); i++ {
+                                               keepAlive(i)
+                                       }
                                }
-                               x := *xp
-                               if x.Type.IsPtr() {
-                                       x = ordercopyexpr(x, x.Type, order, 0)
-                                       x.Name.SetKeepalive(true)
-                                       *xp = x
+                       } else {
+                               if t.Note == unsafeUintptrTag || t.Note == uintptrEscapesTag {
+                                       keepAlive(i)
                                }
                        }
-                       next := it.Next()
-                       if next == nil && t.Isddd() && t.Note == uintptrEscapesTag {
-                               next = t
-                       }
-                       t = next
                }
        }
 }
index b358db2d0d5d021f37e4c3532fee1c6b591577b9..23ba48303b42ebea4d70db0781ebb6b700677d33 100644 (file)
@@ -655,19 +655,32 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo
        assumedEqual[typePair{t1, t2}] = struct{}{}
 
        switch t1.Etype {
-       case TINTER, TSTRUCT:
-               t1, i1 := iterFields(t1)
-               t2, i2 := iterFields(t2)
-               for ; t1 != nil && t2 != nil; t1, t2 = i1.Next(), i2.Next() {
-                       if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, cmpTags, assumedEqual) || cmpTags && t1.Note != t2.Note {
+       case TINTER:
+               if t1.NumFields() != t2.NumFields() {
+                       return false
+               }
+               for i, f1 := range t1.FieldSlice() {
+                       f2 := t2.Field(i)
+                       if f1.Sym != f2.Sym || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
                                return false
                        }
                }
+               return true
 
-               if t1 == nil && t2 == nil {
-                       return true
+       case TSTRUCT:
+               if t1.NumFields() != t2.NumFields() {
+                       return false
                }
-               return false
+               for i, f1 := range t1.FieldSlice() {
+                       f2 := t2.Field(i)
+                       if f1.Sym != f2.Sym || f1.Embedded != f2.Embedded || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
+                               return false
+                       }
+                       if cmpTags && f1.Note != f2.Note {
+                               return false
+                       }
+               }
+               return true
 
        case TFUNC:
                // Check parameters and result parameters for type equality.
@@ -675,16 +688,16 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo
                // equality, because they're never relevant.
                for _, f := range paramsResults {
                        // Loop over fields in structs, ignoring argument names.
-                       ta, ia := iterFields(f(t1))
-                       tb, ib := iterFields(f(t2))
-                       for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
-                               if ta.Isddd() != tb.Isddd() || !eqtype1(ta.Type, tb.Type, cmpTags, assumedEqual) {
+                       fs1, fs2 := f(t1).FieldSlice(), f(t2).FieldSlice()
+                       if len(fs1) != len(fs2) {
+                               return false
+                       }
+                       for i, f1 := range fs1 {
+                               f2 := fs2[i]
+                               if f1.Isddd() != f2.Isddd() || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
                                        return false
                                }
                        }
-                       if ta != nil || tb != nil {
-                               return false
-                       }
                }
                return true
 
@@ -716,18 +729,16 @@ func eqtypenoname(t1 *Type, t2 *Type) bool {
                return false
        }
 
-       f1, i1 := iterFields(t1)
-       f2, i2 := iterFields(t2)
-       for {
+       if t1.NumFields() != t2.NumFields() {
+               return false
+       }
+       for i, f1 := range t1.FieldSlice() {
+               f2 := t2.Field(i)
                if !eqtype(f1.Type, f2.Type) {
                        return false
                }
-               if f1 == nil {
-                       return true
-               }
-               f1 = i1.Next()
-               f2 = i2.Next()
        }
+       return true
 }
 
 // Is type src assignment compatible to type dst?
index 61220648cdc75e95a2a5e58eb1b1cf0a5633b6b7..442dd752cc267e69ac6d62602ea13f2473858df3 100644 (file)
@@ -1063,11 +1063,10 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
                        return ssa.CMPgt // bucket maps are least
                } // If t != t.Map.Bucket, fall through to general case
 
-               fallthrough
-       case TINTER:
-               t1, ti := iterFields(t)
-               x1, xi := iterFields(x)
-               for ; t1 != nil && x1 != nil; t1, x1 = ti.Next(), xi.Next() {
+               tfs := t.FieldSlice()
+               xfs := x.FieldSlice()
+               for i := 0; i < len(tfs) && i < len(xfs); i++ {
+                       t1, x1 := tfs[i], xfs[i]
                        if t1.Embedded != x1.Embedded {
                                return cmpForNe(t1.Embedded < x1.Embedded)
                        }
@@ -1081,17 +1080,36 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
                                return c
                        }
                }
-               if t1 != x1 {
-                       return cmpForNe(t1 == nil)
+               if len(tfs) != len(xfs) {
+                       return cmpForNe(len(tfs) < len(xfs))
+               }
+               return ssa.CMPeq
+
+       case TINTER:
+               tfs := t.FieldSlice()
+               xfs := x.FieldSlice()
+               for i := 0; i < len(tfs) && i < len(xfs); i++ {
+                       t1, x1 := tfs[i], xfs[i]
+                       if c := t1.Sym.cmpsym(x1.Sym); c != ssa.CMPeq {
+                               return c
+                       }
+                       if c := t1.Type.cmp(x1.Type); c != ssa.CMPeq {
+                               return c
+                       }
+               }
+               if len(tfs) != len(xfs) {
+                       return cmpForNe(len(tfs) < len(xfs))
                }
                return ssa.CMPeq
 
        case TFUNC:
                for _, f := range recvsParamsResults {
                        // Loop over fields in structs, ignoring argument names.
-                       ta, ia := iterFields(f(t))
-                       tb, ib := iterFields(f(x))
-                       for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
+                       tfs := f(t).FieldSlice()
+                       xfs := f(x).FieldSlice()
+                       for i := 0; i < len(tfs) && i < len(xfs); i++ {
+                               ta := tfs[i]
+                               tb := xfs[i]
                                if ta.Isddd() != tb.Isddd() {
                                        return cmpForNe(!ta.Isddd())
                                }
@@ -1099,8 +1117,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
                                        return c
                                }
                        }
-                       if ta != tb {
-                               return cmpForNe(ta == nil)
+                       if len(tfs) != len(xfs) {
+                               return cmpForNe(len(tfs) < len(xfs))
                        }
                }
                return ssa.CMPeq
index 17301ea820fc0ff81858f03526789a83db8d85c3..f6776994dd105b3ed54644fbe78185c958e8cdaf 100644 (file)
@@ -1604,8 +1604,7 @@ OpSwitch:
                }
 
                if funarg != nil {
-                       _, it := iterFields(funarg) // Skip first field
-                       for t := it.Next(); t != nil; t = it.Next() {
+                       for _, t := range funarg.FieldSlice()[1:] {
                                if assignop(t.Type, n.Type.Elem(), nil) == 0 {
                                        yyerror("cannot append %v value to []%v", t.Type, n.Type.Elem())
                                }
@@ -2591,11 +2590,12 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc
                                        }
                                }
 
-                               tn, it := iterFields(n.Type)
+                               lfs := tstruct.FieldSlice()
+                               rfs := n.Type.FieldSlice()
                                var why string
-                               for _, tl := range tstruct.Fields().Slice() {
+                               for i, tl := range lfs {
                                        if tl.Isddd() {
-                                               for ; tn != nil; tn = it.Next() {
+                                               for _, tn := range rfs[i:] {
                                                        if assignop(tn.Type, tl.Type.Elem(), &why) == 0 {
                                                                if call != nil {
                                                                        yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Elem(), call, why)
@@ -2604,13 +2604,13 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc
                                                                }
                                                        }
                                                }
-
                                                goto out
                                        }
 
-                                       if tn == nil {
+                                       if i >= len(rfs) {
                                                goto notenough
                                        }
+                                       tn := rfs[i]
                                        if assignop(tn.Type, tl.Type, &why) == 0 {
                                                if call != nil {
                                                        yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
@@ -2618,11 +2618,9 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc
                                                        yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
                                                }
                                        }
-
-                                       tn = it.Next()
                                }
 
-                               if tn != nil {
+                               if len(rfs) > len(lfs) {
                                        goto toomany
                                }
                                goto out
@@ -3055,14 +3053,12 @@ func typecheckcomplit(n *Node) *Node {
                bad := 0
                if n.List.Len() != 0 && nokeys(n.List) {
                        // simple list of variables
-                       f, it := iterFields(t)
-
                        ls := n.List.Slice()
-                       for i1, n1 := range ls {
+                       for i, n1 := range ls {
                                setlineno(n1)
-                               ls[i1] = typecheck(ls[i1], Erv)
-                               n1 = ls[i1]
-                               if f == nil {
+                               n1 = typecheck(n1, Erv)
+                               ls[i] = n1
+                               if i >= t.NumFields() {
                                        if bad == 0 {
                                                yyerror("too many values in struct initializer")
                                        }
@@ -3070,6 +3066,7 @@ func typecheckcomplit(n *Node) *Node {
                                        continue
                                }
 
+                               f := t.Field(i)
                                s := f.Sym
                                if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
                                        yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
@@ -3078,11 +3075,9 @@ func typecheckcomplit(n *Node) *Node {
                                n1 = assignconv(n1, f.Type, "field value")
                                n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
                                n1.Xoffset = f.Offset
-                               ls[i1] = n1
-                               f = it.Next()
+                               ls[i] = n1
                        }
-
-                       if f != nil {
+                       if len(ls) < t.NumFields() {
                                yyerror("too few values in struct initializer")
                        }
                } else {
@@ -3384,17 +3379,15 @@ func typecheckas2(n *Node) {
                                goto mismatch
                        }
                        n.Op = OAS2FUNC
-                       t, s := iterFields(r.Type)
-                       for _, n3 := range n.List.Slice() {
-                               if t.Type != nil && n3.Type != nil {
-                                       checkassignto(t.Type, n3)
+                       for i, l := range n.List.Slice() {
+                               f := r.Type.Field(i)
+                               if f.Type != nil && l.Type != nil {
+                                       checkassignto(f.Type, l)
                                }
-                               if n3.Name != nil && n3.Name.Defn == n && n3.Name.Param.Ntype == nil {
-                                       n3.Type = t.Type
+                               if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
+                                       l.Type = f.Type
                                }
-                               t = s.Next()
                        }
-
                        goto out
                }
        }
index db409900b3621b5eaf87ebf7c9697fefc8b21854..45360f48904dd1c6265c7cf020ac42660a6d265c 100644 (file)
@@ -1697,20 +1697,16 @@ func fncall(l *Node, rt *Type) bool {
 // a expression list. called in
 //     expr-list = func()
 func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
-       r, saver := iterFields(nr)
+       if nl.Len() != nr.NumFields() {
+               Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
+       }
 
        var nn, mm Nodes
-       var ullmanOverflow bool
-       var i int
-       for i = 0; i < nl.Len(); i++ {
-               if r == nil {
-                       break
-               }
-               l := nl.Index(i)
+       for i, l := range nl.Slice() {
                if isblank(l) {
-                       r = saver.Next()
                        continue
                }
+               r := nr.Field(i)
 
                // any lv that causes a fn call must be
                // deferred until all the return arguments
@@ -1729,19 +1725,10 @@ func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
                updateHasCall(a)
                if a.HasCall() {
                        Dump("ascompatet ucount", a)
-                       ullmanOverflow = true
+                       Fatalf("ascompatet: too many function calls evaluating parameters")
                }
 
                nn.Append(a)
-               r = saver.Next()
-       }
-
-       if i < nl.Len() || r != nil {
-               Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
-       }
-
-       if ullmanOverflow {
-               Fatalf("ascompatet: too many function calls evaluating parameters")
        }
        return append(nn.Slice(), mm.Slice()...)
 }