some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / ir / exits.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.0.1-2020.1.5/ir/exits.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.0.1-2020.1.5/ir/exits.go
deleted file mode 100644 (file)
index 10cda7b..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-package ir
-
-import (
-       "go/types"
-)
-
-func (b *builder) buildExits(fn *Function) {
-       if obj := fn.Object(); obj != nil {
-               switch obj.Pkg().Path() {
-               case "runtime":
-                       switch obj.Name() {
-                       case "exit":
-                               fn.WillExit = true
-                               return
-                       case "throw":
-                               fn.WillExit = true
-                               return
-                       case "Goexit":
-                               fn.WillUnwind = true
-                               return
-                       }
-               case "github.com/sirupsen/logrus":
-                       switch obj.(*types.Func).FullName() {
-                       case "(*github.com/sirupsen/logrus.Logger).Exit":
-                               // Technically, this method does not unconditionally exit
-                               // the process. It dynamically calls a function stored in
-                               // the logger. If the function is nil, it defaults to
-                               // os.Exit.
-                               //
-                               // The main intent of this method is to terminate the
-                               // process, and that's what the vast majority of people
-                               // will use it for. We'll happily accept some false
-                               // negatives to avoid a lot of false positives.
-                               fn.WillExit = true
-                               return
-                       case "(*github.com/sirupsen/logrus.Logger).Panic",
-                               "(*github.com/sirupsen/logrus.Logger).Panicf",
-                               "(*github.com/sirupsen/logrus.Logger).Panicln":
-
-                               // These methods will always panic, but that's not
-                               // statically known from the code alone, because they
-                               // take a detour through the generic Log methods.
-                               fn.WillUnwind = true
-                               return
-                       case "(*github.com/sirupsen/logrus.Entry).Panicf",
-                               "(*github.com/sirupsen/logrus.Entry).Panicln":
-
-                               // Entry.Panic has an explicit panic, but Panicf and
-                               // Panicln do not, relying fully on the generic Log
-                               // method.
-                               fn.WillUnwind = true
-                               return
-                       case "(*github.com/sirupsen/logrus.Logger).Log",
-                               "(*github.com/sirupsen/logrus.Logger).Logf",
-                               "(*github.com/sirupsen/logrus.Logger).Logln":
-                               // TODO(dh): we cannot handle these case. Whether they
-                               // exit or unwind depends on the level, which is set
-                               // via the first argument. We don't currently support
-                               // call-site-specific exit information.
-                       }
-               }
-       }
-
-       buildDomTree(fn)
-
-       isRecoverCall := func(instr Instruction) bool {
-               if instr, ok := instr.(*Call); ok {
-                       if builtin, ok := instr.Call.Value.(*Builtin); ok {
-                               if builtin.Name() == "recover" {
-                                       return true
-                               }
-                       }
-               }
-               return false
-       }
-
-       // All panics branch to the exit block, which means that if every
-       // possible path through the function panics, then all
-       // predecessors of the exit block must panic.
-       willPanic := true
-       for _, pred := range fn.Exit.Preds {
-               if _, ok := pred.Control().(*Panic); !ok {
-                       willPanic = false
-               }
-       }
-       if willPanic {
-               recovers := false
-       recoverLoop:
-               for _, u := range fn.Blocks {
-                       for _, instr := range u.Instrs {
-                               if instr, ok := instr.(*Defer); ok {
-                                       call := instr.Call.StaticCallee()
-                                       if call == nil {
-                                               // not a static call, so we can't be sure the
-                                               // deferred call isn't calling recover
-                                               recovers = true
-                                               break recoverLoop
-                                       }
-                                       if len(call.Blocks) == 0 {
-                                               // external function, we don't know what's
-                                               // happening inside it
-                                               //
-                                               // TODO(dh): this includes functions from
-                                               // imported packages, due to how go/analysis
-                                               // works. We could introduce another fact,
-                                               // like we've done for exiting and unwinding,
-                                               // but it doesn't seem worth it. Virtually all
-                                               // uses of recover will be in closures.
-                                               recovers = true
-                                               break recoverLoop
-                                       }
-                                       for _, y := range call.Blocks {
-                                               for _, instr2 := range y.Instrs {
-                                                       if isRecoverCall(instr2) {
-                                                               recovers = true
-                                                               break recoverLoop
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               if !recovers {
-                       fn.WillUnwind = true
-                       return
-               }
-       }
-
-       // TODO(dh): don't check that any specific call dominates the exit
-       // block. instead, check that all calls combined cover every
-       // possible path through the function.
-       exits := NewBlockSet(len(fn.Blocks))
-       unwinds := NewBlockSet(len(fn.Blocks))
-       for _, u := range fn.Blocks {
-               for _, instr := range u.Instrs {
-                       if instr, ok := instr.(CallInstruction); ok {
-                               switch instr.(type) {
-                               case *Defer, *Call:
-                               default:
-                                       continue
-                               }
-                               if instr.Common().IsInvoke() {
-                                       // give up
-                                       return
-                               }
-                               var call *Function
-                               switch instr.Common().Value.(type) {
-                               case *Function, *MakeClosure:
-                                       call = instr.Common().StaticCallee()
-                               case *Builtin:
-                                       // the only builtins that affect control flow are
-                                       // panic and recover, and we've already handled
-                                       // those
-                                       continue
-                               default:
-                                       // dynamic dispatch
-                                       return
-                               }
-                               // buildFunction is idempotent. if we're part of a
-                               // (mutually) recursive call chain, then buildFunction
-                               // will immediately return, and fn.WillExit will be false.
-                               if call.Package() == fn.Package() {
-                                       b.buildFunction(call)
-                               }
-                               dom := u.Dominates(fn.Exit)
-                               if call.WillExit {
-                                       if dom {
-                                               fn.WillExit = true
-                                               return
-                                       }
-                                       exits.Add(u)
-                               } else if call.WillUnwind {
-                                       if dom {
-                                               fn.WillUnwind = true
-                                               return
-                                       }
-                                       unwinds.Add(u)
-                               }
-                       }
-               }
-       }
-
-       // depth-first search trying to find a path to the exit block that
-       // doesn't cross any of the blacklisted blocks
-       seen := NewBlockSet(len(fn.Blocks))
-       var findPath func(root *BasicBlock, bl *BlockSet) bool
-       findPath = func(root *BasicBlock, bl *BlockSet) bool {
-               if root == fn.Exit {
-                       return true
-               }
-               if seen.Has(root) {
-                       return false
-               }
-               if bl.Has(root) {
-                       return false
-               }
-               seen.Add(root)
-               for _, succ := range root.Succs {
-                       if findPath(succ, bl) {
-                               return true
-                       }
-               }
-               return false
-       }
-
-       if exits.Num() > 0 {
-               if !findPath(fn.Blocks[0], exits) {
-                       fn.WillExit = true
-                       return
-               }
-       }
-       if unwinds.Num() > 0 {
-               seen.Clear()
-               if !findPath(fn.Blocks[0], unwinds) {
-                       fn.WillUnwind = true
-                       return
-               }
-       }
-}
-
-func (b *builder) addUnreachables(fn *Function) {
-       for _, bb := range fn.Blocks {
-               for i, instr := range bb.Instrs {
-                       if instr, ok := instr.(*Call); ok {
-                               var call *Function
-                               switch v := instr.Common().Value.(type) {
-                               case *Function:
-                                       call = v
-                               case *MakeClosure:
-                                       call = v.Fn.(*Function)
-                               }
-                               if call == nil {
-                                       continue
-                               }
-                               if call.Package() == fn.Package() {
-                                       // make sure we have information on all functions in this package
-                                       b.buildFunction(call)
-                               }
-                               if call.WillExit {
-                                       // This call will cause the process to terminate.
-                                       // Remove remaining instructions in the block and
-                                       // replace any control flow with Unreachable.
-                                       for _, succ := range bb.Succs {
-                                               succ.removePred(bb)
-                                       }
-                                       bb.Succs = bb.Succs[:0]
-
-                                       bb.Instrs = bb.Instrs[:i+1]
-                                       bb.emit(new(Unreachable), instr.Source())
-                                       addEdge(bb, fn.Exit)
-                                       break
-                               } else if call.WillUnwind {
-                                       // This call will cause the goroutine to terminate
-                                       // and defers to run (i.e. a panic or
-                                       // runtime.Goexit). Remove remaining instructions
-                                       // in the block and replace any control flow with
-                                       // an unconditional jump to the exit block.
-                                       for _, succ := range bb.Succs {
-                                               succ.removePred(bb)
-                                       }
-                                       bb.Succs = bb.Succs[:0]
-
-                                       bb.Instrs = bb.Instrs[:i+1]
-                                       bb.emit(new(Jump), instr.Source())
-                                       addEdge(bb, fn.Exit)
-                                       break
-                               }
-                       }
-               }
-       }
-}