https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899
--- Comment #6 from Jan Hubicka <hubicka at gcc dot gnu.org> --- The problem here is that after gimplification we make no distinction between original pointer and pointer returned by placement new. If one can placement new different type to object into arbitrary field of structure, probably one can do it also for automatic and static variables. So we would need to anticipate dynamic type changes absolutely everywhere. This would more or less disable nonspeculative devirtualization completely because in most cases there is some function call between constructor and use of values which prevents us from proving that the value did not change. What we could do is to keep new operations represented in gimple form until later stages of compilation (remove them soonish after IPA is done). So having osmething like new_ptr = __builtin_placement_new (oldptr) which would also hold type of the allocated value (not sure how to do that without having declaration of biultin_placement_new for every type but even that would work well for me). This would be useful information because devirt machinery then could expect that the dynamic type did not change for all polymorphic types and subtypes. Would that make sense to you? Probably something for next stage1 though.