https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61659
Jan Hubicka <hubicka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at redhat dot com --- Comment #7 from Jan Hubicka <hubicka at gcc dot gnu.org> --- Jason, it seems that the symbol in question is getting into symtab as: _ZN6parserIiE9getOptionEv/21 (void parser<DataType>::getOption() [with DataType = int]) @0x7ffff6c665c0 Type: function Visibility: external public virtual References: Referring: Availability: not_available First run: 0 Function flags: Called by: _ZN4list19getExtraOptionNamesEv/1 (1.00 per call) (can throw external) Calls: I think it should be declared comdat that would make us to output the body. Perhaps it somehow misses import/export decl? The devirtualization happens as part of normal folding in early inline. We inline: void generic_parser_base::getExtraOptionNames() (struct generic_parser_base * const this) { int (*__vtbl_ptr_type) () * _3; int (*__vtbl_ptr_type) () _4; <bb 2>: _3 = this_2(D)->_vptr.generic_parser_base; _4 = *_3; OBJ_TYPE_REF(_4;(struct generic_parser_base)this_2(D)->0) (this_2(D)); return; } to virtual void list::getExtraOptionNames() (struct list * const this) { struct generic_parser_base * _2; <bb 2>: _2 = &this_1(D)->Parser.D.2262.D.2251; generic_parser_base::getExtraOptionNames (_2); return; } this makes base type known and given the visibility we just fold it.