https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82052

--- Comment #3 from Jeffrey A. Law <law at redhat dot com> ---
What an interesting little bug.  A patch is in testing.

The reason it's so hard to trigger is you need a very specific and presumably
unusual set of circumstances to trigger the bug.

Enter object1 into slot X
Enter object2 into slot Y (after rehashing due to conflict)

Y must be < X to trigger the bug because the next step requires a reallocation
of the table.  WHen we reallocate we walk through the old table from first to
last and insert the objects into the new table.

That results in object2 going into slot X and object1 going into slot Y in the
new table.

Then we remove object2 from the hash table.  This leaves slot X in a deleted
state.

Then we lookup object3 and get back slot X which will be put into an empty
state.  Since we didn't get a hit in the table, we try to lookup an alternate
form that would allow us to prove object3 has a constant value.  That succeeds
and we never re-initialize slot X, leaving it in the deleted state.

The deleted state is important as it also means uninitialized.  The generic
bits of hash-table.h (reasonably) assume that a slot in the empty/uninitialized
state  implies that no other objects with a conflicting hash are in the table.

So when we try to lookup object1 in the table, it misses because slot1 is
uninitialized/empty -- which triggers the assert as we know object1 must be in
the hash table.

The fix is to ensure we initialize the slot properly after a miss, but when we
are able to prove the expression has a constant value.

Reply via email to