On Wed, Mar 13, 2019 at 10:08:09PM -0400, Jason Merrill wrote:
> > The following testcase ICEs since my recent cxx_eval_loop_expr changes.
> > The problem is that the Forget saved values of SAVE_EXPRs. inside of the
> > loop can remove SAVE_EXPRs from new_ctx.values and if that is the last
> > iteration, we can also do the loop at the end of function (which has been
> > added there mainly to handle cases where the main loop breaks earlier)
> > and new_ctx.values->remove ICEs because *iter is already not in the table.
> 
> It shouldn't ICE, remove_elt_with_hash is documented to do nothing if the
> element is not in the table.
> 
> Does this untested patch fix the test?

This changed in https://gcc.gnu.org/ml/gcc-patches/2000-02/msg00988.html
Before that change, it has been documented that:
"Naturally the hash table must already exist."
That patch changed it to do
  slot = htab_find_slot (htab, element, 0);
  if (*slot == EMPTY_ENTRY)
    return;
but htab_find_slot actually never returns *slot == EMPTY_ENTRY if called
with insert 0:
+         if (!insert)
+           return NULL;
It can return *slot == EMPTY_ENTRY only if insert is non-zero, and
otherwise it must be (for both cases) a non-deleted non-empty entry equal to
the one we are looking for.

Thus, I believe what is documented since that patch has never worked and we
are wasting cycles (if not optimized out) testing something impossible.

So, I think our options are either to make it work, like below (untested),
or remove those ifs altogether and put back the
"Naturally the hash table must already exist." comment.

2019-03-14  Jason Merrill  <ja...@redhat.com>
            Jakub Jelinek  <ja...@redhat.com>

        * hash-table.h (remove_elt_with_hash): Return if slot is NULL rather
        than if is_empty (*slot).

        * hashtab.c (htab_remove_elt_with_hash): Return if slot is NULL rather
        than if *slot is HTAB_EMPTY_ENTRY.

--- gcc/hash-table.h.jj 2019-01-01 12:37:17.446970209 +0100
+++ gcc/hash-table.h    2019-03-14 08:48:18.861131498 +0100
@@ -940,7 +940,7 @@ hash_table<Descriptor, Allocator>
 ::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
 {
   value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
-  if (is_empty (*slot))
+  if (slot == NULL)
     return;
 
   Descriptor::remove (*slot);
--- libiberty/hashtab.c.jj      2019-01-01 12:38:46.868503025 +0100
+++ libiberty/hashtab.c 2019-03-14 08:47:49.172612001 +0100
@@ -725,7 +725,7 @@ htab_remove_elt_with_hash (htab_t htab,
   PTR *slot;
 
   slot = htab_find_slot_with_hash (htab, element, hash, NO_INSERT);
-  if (*slot == HTAB_EMPTY_ENTRY)
+  if (slot == NULL)
     return;
 
   if (htab->del_f)


        Jakub

Reply via email to