Checks addresses are in the correct segments and creates or updates
        MemoryData in _memory_data as appropriate, labelling as segment
        boundaries or data type

        :param int irsb_addr: irsb address
        :param int stmt_idx: Statement ID
        :param int insn_addr: instruction address
        :param data_addr: address of data manipulated by statement
        :param data_size: Size of the data being manipulated
        :param str data_type: Type of the data being manipulated
        :return: None

def _add_data_reference(self, irsb_addr, stmt_idx, insn_addr, data_addr,  # pylint: disable=unused-argument
                            data_size=None, data_type=None):
        """
        Checks addresses are in the correct segments and creates or updates
        MemoryData in _memory_data as appropriate, labelling as segment
        boundaries or data type

        :param int irsb_addr: irsb address
        :param int stmt_idx: Statement ID
        :param int insn_addr: instruction address
        :param data_addr: address of data manipulated by statement
        :param data_size: Size of the data being manipulated
        :param str data_type: Type of the data being manipulated
        :return: None
        """

        # Make sure data_addr is within a valid memory range
        if not self.project.loader.find_segment_containing(data_addr):

            # data might be at the end of some section or segment...
            # let's take a look
            for segment in self.project.loader.main_object.segments:
                if segment.vaddr + segment.memsize == data_addr:
                    # yeah!
                    new_data = False
                    if data_addr not in self._memory_data:
                        data = MemoryData(data_addr, 0, MemoryDataSort.SegmentBoundary)
                        self._memory_data[data_addr] = data
                        new_data = True

                    if new_data or self._extra_cross_references:
                        cr = CodeReference(insn_addr, irsb_addr, stmt_idx, memory_data=self.model.memory_data[data_addr])
                        self.model.references.add_ref(cr)
                    break

            return

        new_data = False
        if data_addr not in self._memory_data:
            if data_type is not None and data_size is not None:
                data = MemoryData(data_addr, data_size, data_type, max_size=data_size)
            else:
                data = MemoryData(data_addr, 0, MemoryDataSort.Unknown)
            self._memory_data[data_addr] = data
            new_data = True
        if new_data or self._extra_cross_references:
            cr = CodeReference(insn_addr, irsb_addr, stmt_idx, memory_data=self.model.memory_data[data_addr])
            self.model.references.add_ref(cr)

        self.insn_addr_to_memory_data[insn_addr] = self._memory_data[data_addr]