docs: def _handle_control_dependence(self, target_node):
          """
          Based on control dependence graph, pick all exits (statements) that lead to the target.
  
          :param target_node: A CFGNode instance.
          :returns:           A set of new tainted code locations.
          """
  
          new_taints = set()
  
          # Query the CDG and figure out all control flow transitions to reach this target
          cdg_guardians = self._cdg.get_guardians(target_node)
          if not cdg_guardians:
              # this block is directly reachable from the entry point
              pass
  
          else:
              # For each predecessor on CDG, find the correct exit to take, and continue slicing from those exits
              for predecessor in cdg_guardians:
                  exits = self._find_exits(predecessor, target_node)
  
                  for stmt_idx, target_addresses in exits.items():
                      if stmt_idx is not None:
                          # If it's an exit statement, mark it as picked
                          self._pick_statement(predecessor.addr,
                                               self._normalize_stmt_idx(predecessor.addr, stmt_idx)
                                               )
                          # If it's the default statement, we should also pick other conditional exit statements
                          if stmt_idx == DEFAULT_STATEMENT:
                              conditional_exits = self._conditional_exits(predecessor.addr)
                              for conditional_exit_stmt_id in conditional_exits:
                                  cl = CodeLocation(predecessor.addr,
                                                    self._normalize_stmt_idx(predecessor.addr, conditional_exit_stmt_id)
                                                    )
                                  new_taints.add(cl)
  
                                  self._pick_statement(predecessor.addr,
                                                       self._normalize_stmt_idx(predecessor.addr, conditional_exit_stmt_id)
                                                       )
  
                      if target_addresses is not None:
  
                          if stmt_idx is not None:
                              # If it's an exit statement, we create a new tainted code location
                              cl = CodeLocation(predecessor.addr,
                                                self._normalize_stmt_idx(predecessor.addr, stmt_idx)
                                                )
                              new_taints.add(cl)
  
                          # Mark those exits as picked
                          for target_address in target_addresses:
                              self._pick_exit(predecessor.addr, stmt_idx, target_address)
  
                      # On CFG, pick default exits of all nodes between predecessor and our target node
                      # Usually this is not required if basic blocks strictly end at control flow transitions. But this is
                      # not always the case for some architectures
                      all_simple_paths = list(networkx.all_simple_paths(self._cfg.graph, predecessor, target_node, cutoff=3))
  
                      previous_node = None
                      for path in all_simple_paths:
                          for node in path:
                              self._pick_statement(node.addr,
                                                   self._normalize_stmt_idx(node.addr, DEFAULT_STATEMENT))
                              if previous_node is not None:
                                  self._pick_exit(previous_node.addr, DEFAULT_STATEMENT, node.addr)
  
          return new_taints