To quote C99 section 6.5.7 "Bitwise shift operators":
The result of E1 << E2 is E1 left-shifted E2 bit positions;
vacated bits are filled with zeros. ... If E1 has a signed
type and nonnegative value, and E1 x 2^E2 is representable in
the result type, then that is the resulting value; otherwise,
the behavior is undefined.
In practice, this is harmless, as long as we don't get a trap of some
sort in the "isn't representable" case, but we might as well do an
unsigned shift - it's just doing hashing, so as long as all the relevant
bits get hashed in, that's good enough.