Possible fix for issue with computation type for compound assignment

Take the following C snippet:
void a(unsigned char* a, unsigned b) {*a <<= b;}

clang currently compiles this down to a shift of width i8. This is
incorrect; per the C standard, the shift should occur in the type int.
The difference doesn't really matter for codegen of a lot of
operations: for example, if a and b are of type unsigned char, a+b can
be computed in the width of unsigned char without affecting the
result. However, it does matter for some operations: in LLVM, shifts
greater than the width of the left operand are undefined. Another
case where this matters:
void a(signed char* a, signed char b) {*a /= b;}
In this case, if a is -128 and b is -1, the correct result (using
clang's definition of signed integer conversion) is -128; however,
using the LLVM sdiv operator on i8, the result is undefined (and
actually crashes on X86).

Attached patch fixes Sema to return the correcct computation type for
these cases. I'm not completely confident my fix is the right way to
fix this, though.

-Eli

tt.txt (3.02 KB)

I think I'd like some sort of review for this patch before I commit it.

-Eli