https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64922
--- Comment #12 from Jan Hubicka <hubicka at gcc dot gnu.org> --- OK, the devirtualization I see is for _Z3getI10Code_BlockEbR2CSRKSsPT_.part.3.constprop.7 when it is inlined to _ZN4FileC2ERKSs outer type of original context is: $6 = {offset = 0, speculative_offset = 0, outer_type = 0x7ffff631f498, speculative_outer_type = 0x0, maybe_in_construction = 0, maybe_derived_type = 1, where outer_type is Code_Block. It gets combined with: $10 = {offset = 0, speculative_offset = 0, outer_type = 0x7ffff6cb0000, speculative_outer_type = 0x0, maybe_in_construction = 0, maybe_derived_type = 0, speculative_maybe_derived_type = 0, invalid = 0, dynamic = 1} where outer_type is basic_string These two types are not related, so we go for invalid. The first type is derived from fact that operator >> takes reference to Code_Block that seems OK. The other is determined by std::basic_string<char>::basic_string (&D.13149, "X", &D.13150); that is passed to _62 = get<Code_Block> (_30, &D.13149, _36); So I think we confuse argument 2 of get<Code_Block> with argument 1 of get<Code_Block>.part.3.