https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118790
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |rguenth at gcc dot gnu.org --- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> --- 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, 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?