https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117047
--- Comment #39 from Richard Biener <rguenth at gcc dot gnu.org> --- playback::rvalue * playback::context:: new_bitcast (location *loc, rvalue *expr, type *type_) { tree expr_size = TYPE_SIZE (expr->get_type ()->as_tree ()); Hmm, so the issue is likely that the GC allocated object expr->get_type () allocates does not escape anywhere and thus when DSE does not find any use of the vtable pointer it removes the store, not realizing that the actual use is a defered GC walk and invocation of a DTOR. So indeed it seems that those allocation functions are not suitable 'malloc' functions given their result escape to the GC. That's independent on whether any of the alloc/free are inlined. It works just fine when there's no finalizer as there's nothing to preserve in the objects when they are trivially "dead", but when a finalizer invokes a DTOR then of course that can read from the objects contents. So a less radical approach would be to make only the allocation functions without a finalizer 'malloc'.