There are may things in C which cause UB.
Most of them are ok to do so, but there are several ones where implementation-defined behaviour would be more logical. Let me have an example:
Concerning the <<
operator,
If E1 has a signed type and nonnegative value, and E1 × 2 E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
That means that
signed char r = 0x40;
r <<= 2;
is UB where IB would IMO be more logical.
Is an implementation allowed to define what happens here?