This one made me think:
class X;
void foo(X* p)
{
delete p;
}
How can we possibly delete p if we do not even know whether
From the standard [expr.delete]:
If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.
So, it's UB if there's nontrivial stuff to do, and it's ok if there isn't. Warnings aren't neccessary for UB.