https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69589
--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> --- The node is added to reachable set in symbol_table::remove_unreachable_nodes because of following condition is true: /* If any symbol in a comdat group is reachable, force all externally visible symbols in the same comdat group to be reachable as well. Comdat-local symbols can be discarded if all uses were inlined. */ if (node->same_comdat_group) { symtab_node *next; for (next = node->same_comdat_group; next != node; next = next->same_comdat_group) if (!next->comdat_local_p () && !reachable.add (next)) enqueue_node (next, &first, &reachable); } Where node->debug(): (gdb) p node->debug() _ZN2JS3ubi20PreComputedEdgeRangeD0Ev/73129 (__deleting_dtor ) @0x7ffff56702e0 Type: function definition analyzed Visibility: externally_visible prevailing_def_ironly public weak comdat comdat_group:_ZN2JS3ubi20PreComputedEdgeRangeD5Ev one_only visibility_specified visibility:hidden virtual artificial Same comdat group as: _ZN2JS3ubi20PreComputedEdgeRangeD2Ev/73127 Address is taken. Aux: @0x7ffff5667000 References: Referring: _ZTVN2JS3ubi20PreComputedEdgeRangeE/73125 (addr) Read from file: Unified_cpp_js_src35.o First run: 0 Function flags: merged_comdat Called by: Calls: _ZdlPvm/39897 (1.00 per call) I've been still reducing the test-case, currently the total size is about 5.5MB. Martin