The penultimate example tripped me up. I was under the impression that arithmetic conversions for binary operators only happened if the types of the operands were different. But reading the standard, and then actually experimenting with clang and __auto_type, does confirm that if the operands can be converted to int or unsigned int, then they will be (and that it will convert to int if int can represent all the values). That's really kind of nasty given the lack of wrapping overflow on signed integers.
This actually makes me wonder, if I do want wrapping overflow on signed integers in C, how do I request it? Is there some compiler builtin or stdlib function to say "please add/multiply/whatever these signed integers with overflow"?