https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118790
--- Comment #21 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #12) > This looks like a GC bug. > On the id_string.55 DECL_HAS_VALUE_EXPR_P bit is set and DECL_VALUE_EXPR is > set to > COMPONENT_REF during streaming in. > But then > #0 pointer_hash<tree_decl_map>::mark_deleted (e=@0x7fffea128850: 0x1) at > ../../gcc/hash-traits.h:204 > #1 0x000000000110d844 in hash_table<tree_decl_map_cache_hasher, false, > xcallocator>::mark_deleted (v=@0x7fffea128850: 0x1) at > ../../gcc/hash-table.h:552 > #2 0x000000000110b81c in hash_table<tree_decl_map_cache_hasher, false, > xcallocator>::clear_slot (this=0x7fffea12a070, slot=0x7fffea128850) at > ../../gcc/hash-table.h:969 > #3 0x0000000001107f8c in gt_cleare_cache<tree_decl_map_cache_hasher> > (h=0x7fffea12a070) at ../../gcc/hash-table.h:1315 > #4 0x0000000001104afe in gt_clear_caches_gt_tree_h () at ./gt-tree.h:497 > #5 0x000000000044c95a in gt_clear_caches () at ./gtype-lto.h:1926 > #6 0x0000000000771633 in ggc_mark_roots () at ../../gcc/ggc-common.cc:112 > #7 0x0000000000490cb8 in ggc_collect (mode=GGC_COLLECT_HEURISTIC) at > ../../gcc/ggc-page.cc:2231 > #8 0x0000000000b0ce79 in execute_one_pass (pass=<opt_pass* 0x3d1db80 > "expand"(277)>) at ../../gcc/passes.cc:2751 > marks the it in the value_expr_for_decl as deleted, because is ggc_marked_p > false on it. > But that very same id_string.55 var is then ggc_set_mark marked because > there is > id_string var with *id_string.55 DECL_VALUE_EXPR later in the > value_expr_for_decl hash table. > > gt_cleare_cache does only one pass through a hash_map: > for (typename table::iterator iter = h->begin (); iter != h->end (); > ++iter) > if (!table::is_empty (*iter) && !table::is_deleted (*iter)) > { > int res = H::keep_cache_entry (*iter); > if (res == 0) > h->clear_slot (&*iter); > else if (res != -1) > H::ggc_mx (*iter); > } So the issue is not that we remove id_string.55 var from the hash but that somehow marking the id_string.55 using *id_string.55 faults then? Why? Is that really *X with X DECL_VALUE_EXPR being id_string.55 again and X isn't marked before we process this hashtable? > So, either the VAR_DECL should be reachable from something other than > DECL_VALUE_EXPR expressions (bet it was originally in local decls of > something), or we need to have two passes over hash_maps, in the first pass > just H::ggc_mx (*iter) on entries where res is not 0 nor -1, and in the > second pass clear_slot of res is 0. > Guess that needs to be done only for hash tables where keep_cache_entry > returns 0/1 rather than 0/-1, though no idea how to that out during > instantiation. > And I wonder about references from multiple cache hash maps, say > DECL_DEBUG_EXPR refers to something which has DECL_VALUE_EXPR or vice versa. > Wouldn't we then need to do it always in two passes for all the cache hash > tables, > during proper marking walk all those hash tables and just H::ggc_mx (*iter) > when keep_cache_entry returns 1, and then once everything is marked repeat > the walks and only do the clear_slot? I think the VAR_DECL should be reachable from elsewhere (BLOCK_VARS ideally, I'd like to get rid of local_decls). IIRC I wondered at some point whether remove_unused_locals needs to walk DECL_VALUE_EXPRs but I think I went down an alternate place for the fix/PR I'm remembering (which now makes it difficult to track down...).