Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -8536,8 +8536,13 @@ return meet; } + case BO_Mul: { + // The result width should be calculated in advance + unsigned opWidth = C.getIntWidth(GetExprType(E)); + return IntRange(opWidth, false); + } + // The default behavior is okay for these. - case BO_Mul: case BO_Add: case BO_Xor: case BO_Or: Index: test/Sema/conversion.c =================================================================== --- test/Sema/conversion.c +++ test/Sema/conversion.c @@ -302,7 +302,7 @@ } void test15(char c) { - c = c + 1 + c * 2; + c = c + 1 + c * 2; // expected-warning {{implicit conversion loses integer precision: 'int'}} c = (short) c + 1 + c * 2; // expected-warning {{implicit conversion loses integer precision}} } @@ -448,3 +448,11 @@ b -= a; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'double' to 'float'}} return b; } + +unsigned short foo1(unsigned char a) { + return a * a; // expected-warning {{implicit conversion loses integer precision: 'int' to 'unsigned short'}} +} + +signed short bar1(signed char a) { + return a * a; // expected-warning {{implicit conversion loses integer precision: 'int' to 'short'}} +} Index: test/SemaCXX/conversion.cpp =================================================================== --- test/SemaCXX/conversion.cpp +++ test/SemaCXX/conversion.cpp @@ -298,3 +298,15 @@ conditional_run_13(NULL); } } + +template +T mul_t(T a, T b) { + int c = a * b; + T d1 = c; // expected-warning{{implicit conversion loses integer precision: 'int' to 'char'}} + T d2 = a * b; // expected-warning{{implicit conversion loses integer precision: 'int' to 'char'}} + return d1 + d2; +} + +char mul_t_test (char a, char b) { + return mul_t(a, b); // expected-note{{in instantiation of function template specialization 'mul_t' requested here}} +}