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

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