https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78665
--- Comment #2 from Richard W.M. Jones <rjones at redhat dot com> ---
The code which calculates seg_len is surely quite interesting in that case:
size_t seg_len = block_len (h, blkoff, &used);
if (seg_len <= 4 || (seg_len & 3) != 0) {
The block_len function which is probably inlined is:
static inline size_t
block_len (hive_h *h, size_t blkoff, int *used)
{
struct ntreg_hbin_block *block;
block = (struct ntreg_hbin_block *) ((char *) h->addr + blkoff);
int32_t len = le32toh (block->seg_len);
if (len < 0) {
if (used) *used = 1;
len = -len;
} else {
if (used) *used = 0;
}
return (size_t) len;
}
The original data format (a Windows NT registry) encodes a 32 bit block
length into every header, and negates this length field if the block is
marked as "used" (it's positive if the block is free).
I can't recall if converting int32_t -> (64 bit) size_t is safe or not.