diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index a3a0970f71..c6e94cc4b3 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -463,9 +463,8 @@ func walkclosure(func_ *Node, init *Nodes) *Node { Warnl(func_.Pos, "closure converted to global") } return func_.Func.Closure.Func.Nname - } else { - closuredebugruntimecheck(func_) } + closuredebugruntimecheck(func_) // Create closure in the form of a composite literal. // supposing the closure captures an int i and a string s diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 87a5b7f29f..afe1e5a7e5 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -1554,20 +1554,20 @@ func (e *EscState) esccall(call *Node, parent *Node) { call.Right = arg } e.escassignWhyWhere(n, arg, "arg to recursive call", call) // TODO this message needs help. - if arg != args[0] { - // "..." arguments are untracked - for _, a := range args { - if Debug['m'] > 3 { - fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a) - } - e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call) - } - // No more PPARAM processing, but keep - // going for PPARAMOUT. - args = nil + if arg == args[0] { + args = args[1:] continue } - args = args[1:] + // "..." arguments are untracked + for _, a := range args { + if Debug['m'] > 3 { + fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a) + } + e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call) + } + // No more PPARAM processing, but keep + // going for PPARAMOUT. + args = nil case PPARAMOUT: cE.Retval.Append(n) diff --git a/src/cmd/compile/internal/gc/phi.go b/src/cmd/compile/internal/gc/phi.go index 0ce7a4b11d..b549f0ea6f 100644 --- a/src/cmd/compile/internal/gc/phi.go +++ b/src/cmd/compile/internal/gc/phi.go @@ -233,24 +233,25 @@ func (s *phiState) insertVarPhis(n int, var_ *Node, defs []*ssa.Block, typ *type // a D-edge, or an edge whose target is in currentRoot's subtree. continue } - if !hasPhi.contains(c.ID) { - // Add a phi to block c for variable n. - hasPhi.add(c.ID) - v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right? - // Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building. - s.s.addNamedValue(var_, v) - for i := 0; i < len(c.Preds); i++ { - v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs. - } - if debugPhi { - fmt.Printf("new phi for var%d in %s: %s\n", n, c, v) - } - if !hasDef.contains(c.ID) { - // There's now a new definition of this variable in block c. - // Add it to the priority queue to explore. - heap.Push(priq, c) - hasDef.add(c.ID) - } + if hasPhi.contains(c.ID) { + continue + } + // Add a phi to block c for variable n. + hasPhi.add(c.ID) + v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right? + // Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building. + s.s.addNamedValue(var_, v) + for i := 0; i < len(c.Preds); i++ { + v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs. + } + if debugPhi { + fmt.Printf("new phi for var%d in %s: %s\n", n, c, v) + } + if !hasDef.contains(c.ID) { + // There's now a new definition of this variable in block c. + // Add it to the priority queue to explore. + heap.Push(priq, c) + hasDef.add(c.ID) } } diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index a08ea0f73b..745a1efce8 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -497,14 +497,12 @@ func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int { func isExportedField(ft *types.Field) (bool, *types.Pkg) { if ft.Sym != nil && ft.Embedded == 0 { return exportname(ft.Sym.Name), ft.Sym.Pkg - } else { - if ft.Type.Sym != nil && - (ft.Type.Sym.Pkg == builtinpkg || !exportname(ft.Type.Sym.Name)) { - return false, ft.Type.Sym.Pkg - } else { - return true, nil - } } + if ft.Type.Sym != nil && + (ft.Type.Sym.Pkg == builtinpkg || !exportname(ft.Type.Sym.Name)) { + return false, ft.Type.Sym.Pkg + } + return true, nil } // dnameField dumps a reflect.name for a struct field. diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index 613cdf6e74..f38692e310 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -480,9 +480,8 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { n := *l gdata(&n, r.Func.Closure.Func.Nname, Widthptr) return true - } else { - closuredebugruntimecheck(r) } + closuredebugruntimecheck(r) case OCONVIFACE: // This logic is mirrored in isStaticCompositeLiteral. diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 932d1f2b70..faaeed6a33 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -661,24 +661,26 @@ func (s *state) stmt(n *Node) { } rhs = nil case OAPPEND: - // If we're writing the result of an append back to the same slice, - // handle it specially to avoid write barriers on the fast (non-growth) path. + // Check whether we're writing the result of an append back to the same slice. + // If so, we handle it specially to avoid write barriers on the fast + // (non-growth) path. + if !samesafeexpr(n.Left, rhs.List.First()) { + break + } // If the slice can be SSA'd, it'll be on the stack, // so there will be no write barriers, // so there's no need to attempt to prevent them. - if samesafeexpr(n.Left, rhs.List.First()) { - if !s.canSSA(n.Left) { - if Debug_append > 0 { - Warnl(n.Pos, "append: len-only update") - } - s.append(rhs, true) - return - } else { - if Debug_append > 0 { // replicating old diagnostic message - Warnl(n.Pos, "append: len-only update (in local slice)") - } + if s.canSSA(n.Left) { + if Debug_append > 0 { // replicating old diagnostic message + Warnl(n.Pos, "append: len-only update (in local slice)") } + break } + if Debug_append > 0 { + Warnl(n.Pos, "append: len-only update") + } + s.append(rhs, true) + return } } diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index ab68c515ad..b809a8bee7 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -2636,54 +2636,52 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, n = nil if nl.Len() == 1 { n = nl.First() - if n.Type != nil { - if n.Type.IsFuncArgStruct() { - if !hasddd(tstruct) { - n1 := tstruct.NumFields() - n2 := n.Type.NumFields() - if n2 > n1 { - goto toomany - } - if n2 < n1 { - goto notenough - } - } - - lfs := tstruct.FieldSlice() - rfs := n.Type.FieldSlice() - var why string - for i, tl := range lfs { - if tl.Isddd() { - 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) - } else { - yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why) - } - } - } - goto out - } - - 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) - } else { - yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why) - } - } - } - - if len(rfs) > len(lfs) { + if n.Type != nil && n.Type.IsFuncArgStruct() { + if !hasddd(tstruct) { + n1 := tstruct.NumFields() + n2 := n.Type.NumFields() + if n2 > n1 { goto toomany } - goto out + if n2 < n1 { + goto notenough + } } + + lfs := tstruct.FieldSlice() + rfs := n.Type.FieldSlice() + var why string + for i, tl := range lfs { + if tl.Isddd() { + 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) + } else { + yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Elem(), desc(), why) + } + } + } + goto out + } + + 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) + } else { + yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why) + } + } + } + + if len(rfs) > len(lfs) { + goto toomany + } + goto out } }