https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77947
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- Before r240578 everything prevailed until the very end and the context DIE we tried to force would be still there. In the end everything would get removed again, of course. GCC 6 emits no debug info for m_fn2 or the contained classes/methods (B is also not present). So IMHO avoiding all the work early makes very much sense. IPA says _Z3fn1R1A/8 (void fn1(A&)) @0x7ffbf1620e60 Type: function definition analyzed Visibility: public References: Referring: First run: 0 Function flags: body Called by: Calls: Polymorphic indirect call of type const struct A token:0(1.00 per call) (can throw external) Outer type (dynamic):struct A (or a derived type) (maybe in construction) offset 0 _ZZNK1B5m_fn2EvENK1C5m_fn1Ev/0 (virtual bool B::m_fn2() const::C::m_fn1() const) @0x7ffbf16202e0 which probably means that fn1 (being a global function) could be called from another TU which has B::m_fn2 used (ODR, etc.) and with C as p1. OTOH that's only possible if C "escapes" from B::m_fn2 (though we don't do such analysis). So in the end the speculative devirt is sensible but then reclaiming of B::m_fn2 is a bit over-eager given we later somehow "inline" B::m_fn2::C:m_fn1 (and ICE in that process).