https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87634
--- Comment #2 from Simon Richter <Simon.Richter at hogyros dot de> --- Well, I tried really hard to make a case that makes the second dynamic_cast return null after the first returned non-null. The most promising candidate uses a direct destructor call and placement new on a global pointer that happens to be a copy of the pointer passed into the method. struct C : A { virtual void foo() {} }; unsigned char *storage = new unsigned char[std::max(sizeof(B), sizeof(C))]; B *global_b = new(storage) B; later, call test(global_b); and implement B::foo() as global_b->~B(); new(storage) C; If that is legal C++, then rechecking the dynamic type of the object might make sense, but I'm not entirely sure about whether aliasing rules would break that example.