@ixSci, Похоже, что неопределённое поведение строк кода f(); и pb->f();, которые присутствуют в примере из пункта 6.6.3/6 обусловлено причинами, описанными в пункте 6.6.3/8.
После того, как в функции mutate на месте объекта типа D1 был создан объект типа D2, все указатели и ссылки, которые указывали / ссылались на исходный объект теперь указывают / ссылаются на новый объект. Однако, использовать их для манипулирования новым объектом можно только в том случае, если новый объект имеет тот же самый тип, что и исходный.
Если в mutate написать так: B *p = new (this) D2; p->f();, то это похоже корректный код.