https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95114
Bug ID: 95114 Summary: [9/10/11 Regression] ICE in obj_type_ref_class for structural-equality types Product: gcc Version: 9.0 Status: UNCONFIRMED Keywords: ice-on-valid-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rsandifo at gcc dot gnu.org CC: hubicka at gcc dot gnu.org Target Milestone: --- Target: aarch64*-*-* Since r9-5035-g4611c03d2b0edefc8d8e17872ef143428f56380b, the following testcase has ICEd for aarch64, compiled at -O0: ----------------------------------------------------------- template<typename T> struct foo { virtual void f() = 0; }; extern foo<__Int8x8_t> &x; void f() { x.f(); } ----------------------------------------------------------- The exact ICE has changed over time, but the current form is: ----------------------------------------------------------- during GIMPLE pass: *rebuild_cgraph_edges foo.c: In function ‘void f()’: foo.c:3:19: internal compiler error: Segmentation fault 3 | void f() { x.f(); } | ^ 0x16cfec1 crash_signal src/gcc/gcc/toplev.c:328 0x129a4ca obj_type_ref_class(tree_node const*) src/gcc/gcc/ipa-devirt.c:1915 0x1afe3d7 virtual_method_call_p(tree_node const*) src/gcc/gcc/tree.c:12867 0xf1102b cgraph_node::create_indirect_edge(gcall*, int, profile_count, bool) src/gcc/gcc/cgraph.c:990 0xf2113d cgraph_edge::rebuild_edges() src/gcc/gcc/cgraphbuild.c:421 0xf214aa execute src/gcc/gcc/cgraphbuild.c:490 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. ----------------------------------------------------------- This is because for structural-equality types we call get_odr_type: ----------------------------------------------------------- if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret)) ret = TYPE_CANONICAL (ret); else ret = get_odr_type (ret)->type; ----------------------------------------------------------- and the hash table is empty at this point. (We did previously have a hash entry for the type, but that was freed during pass_ipa_free_lang_data.) The test does pass at -O2, but fails with -fdump-tree-all-details -O2: ----------------------------------------------------------- foo.c: In function ‘void f()’: foo.c:3:19: internal compiler error: Segmentation fault 3 | void f() { x.f(); } | ^ 0x16cfec1 crash_signal src/gcc/gcc/toplev.c:328 0x12a20f8 hash_table<odr_name_hasher, false, xcallocator>::find_slot_with_hash(tree_node* const&, unsigned int, insert_option) src/gcc/gcc/hash-table.h:967 0x129a622 get_odr_type(tree_node*, bool) src/gcc/gcc/ipa-devirt.c:1939 0x129a4c9 obj_type_ref_class(tree_node const*) src/gcc/gcc/ipa-devirt.c:1915 0x1afe3d7 virtual_method_call_p(tree_node const*) src/gcc/gcc/tree.c:12867 0x180f086 dump_generic_node(pretty_printer*, tree_node*, int, dump_flag, bool) src/gcc/gcc/tree-pretty-print.c:3125 ... ----------------------------------------------------------- I guess the fact that this routine is called by the dump routines (which shouldn't affect codegen) suggests that we should cope with null returns from get_odr_type, rather than passing "true" as the insert parameter. Is that right?