This fixes an error in iterative_hash_canonical_type which can
end up writing into the wrong hashtable slot (as it recurses
and thus the hashtable can get re-allocated and re-hashed).

LTO bootstrapped on x86_64-unknown-linux-gnu, applied to trunk.

Probably should be backported as a bogus canonical type can
result in wrong-code generation with LTO.  I'll try to remember
to do that after 4.8.2 is out.

Richard.

2013-10-14  Richard Biener  <rguent...@suse.de>

        PR middle-end/58712
        PR middle-end/55358
        * gimple.c (iterative_hash_canonical_type): Make sure to
        record the hash into the correct hashtable slot.

Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c        (revision 203409)
+++ gcc/gimple.c        (working copy)
@@ -3112,8 +3112,7 @@ iterative_hash_canonical_type (tree type
   struct tree_int_map *mp, m;
 
   m.base.from = type;
-  if ((slot = htab_find_slot (canonical_type_hash_cache, &m, INSERT))
-      && *slot)
+  if ((slot = htab_find_slot (canonical_type_hash_cache, &m, NO_INSERT)))
     return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, val);
 
   /* Combine a few common features of types so that types are grouped into
@@ -3217,6 +3216,10 @@ iterative_hash_canonical_type (tree type
   mp = ggc_alloc_cleared_tree_int_map ();
   mp->base.from = type;
   mp->to = v;
+  /* As we recurse the hashtable may expand between looking up the
+     cached value (and not finding one) and here, so we have to
+     re-lookup the slot.  */
+  slot = htab_find_slot (canonical_type_hash_cache, &m, INSERT);
   *slot = (void *) mp;
 
   return iterative_hash_hashval_t (v, val);

Reply via email to