There's no requirement for the code incurring undefined behaviour to be
executed. The Standard imposes requirements on *translators*, and the
translator sees that code. However, compilation must succeed `unless [the
translator] can determine that every possible execution of that program
would result in undefined behavior' (or there's a syntax error or
constraint violation, neither of which is true here), which could be read
to imply that if the translator can determine that there are several
possible ways to interpret some part of a program, some undefined and some
not, the translator must assume that the not-undefined interpretation
holds.
This sometimes has incredibly counterintuitive consequences, so as a QoI
issue it is not always followed. (e.g. in this case I suspect it would be
permitted for a compiler to spot that the problematic code is not executed
if malloc() always returns NULL, and expand the appropriate malloc() calls
inline to a constant NULL on the basis that returning anything else would
incur undefined behaviour! In practice, this wouldn't get done.)