https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105285
--- Comment #6 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
For (a):
If I'm reading this right:
reader_init_block_reader has:
struct reftable_block block = {((void *)0)};
reader_init_block_reader checks for (next_off >= r->size) and bails out,
otherwise, block is passed to reader_get_block:
if (next_off >= r->size)
return 1;
err = reader_get_block(r, &block, next_off, guess_block_size);
if (err < 0)
goto done;
block_size = extract_block_size(block.data, &block_typ, next_off,
r->version);
There's an early-reject case in reader_get_block, which is:
if (off >= r->size)
return 0;
I believe the analyzer's feasibility checker is getting confused; it appears to
be getting placeholder values when it access r->size, and each time it accesses
r->size it gets a different placeholder value, and thus erroneously considers
the execution path where (next_off >= r->size) && !(off >= r->size) when
next_off == off.
I'm working on a simpler reproducer, and a fix.