docs: def is_taint_related_to_ip(self, simrun_addr, stmt_idx, taint_type, simrun_whitelist=None):
          """
          Query in taint graph to check if a specific taint will taint the IP in the future or not.
          The taint is specified with the tuple (simrun_addr, stmt_idx, taint_type).
  
          :param simrun_addr:         Address of the SimRun.
          :param stmt_idx:            Statement ID.
          :param taint_type:          Type of the taint, might be one of the following: 'reg', 'tmp', 'mem'.
          :param simrun_whitelist:    A list of SimRun addresses that are whitelisted, i.e. the tainted exit will be
                                      ignored if it is in those SimRuns.
          :returns:                   True/False
          """
  
          if simrun_whitelist is None:
              simrun_whitelist = set()
          if type(simrun_whitelist) is not set:
              simrun_whitelist = set(simrun_whitelist)
  
          # Find the specific taint in our graph
          taint = None
          for n in self.taint_graph.nodes():
              if n.type == taint_type and n.addr == simrun_addr and n.stmt_id == stmt_idx:
                  taint = n
                  break
  
          if taint is None:
              raise AngrBackwardSlicingError('The specific taint is not found')
  
          bfs_tree = networkx.bfs_tree(self.taint_graph, taint)
  
          # A node is tainting the IP if one of the following criteria holds:
          # - a descendant tmp variable is used as a default exit or a conditional exit of its corresponding SimRun
          # - a descendant register is the IP itself
  
          for descendant in bfs_tree.nodes():
              if descendant.type == 'exit':
                  if descendant.addr not in simrun_whitelist:
                      return True
              elif descendant.type == 'reg' and descendant.reg == self.project.arch.ip_offset:
                  return True
  
          return False