1 --- gcc/c-typeck.c (revision 110241)
2 +++ gcc/c-typeck.c (working copy)
3 @@ -8101,12 +8101,35 @@ build_binary_op (enum tree_code code, tr
4 if (shorten && none_complex)
6 int unsigned0, unsigned1;
7 - tree arg0 = get_narrower (op0, &unsigned0);
8 - tree arg1 = get_narrower (op1, &unsigned1);
9 - /* UNS is 1 if the operation to be done is an unsigned one. */
10 - int uns = TYPE_UNSIGNED (result_type);
15 + /* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
16 + excessive narrowing when we call get_narrower below. For
17 + example, suppose that OP0 is of unsigned int extended
18 + from signed char and that RESULT_TYPE is long long int.
19 + If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
22 + (long long int) (unsigned int) signed_char
24 + which get_narrower would narrow down to
26 + (unsigned int) signed char
28 + If we do not cast OP0 first, get_narrower would return
29 + signed_char, which is inconsistent with the case of the
31 + op0 = convert (result_type, op0);
32 + op1 = convert (result_type, op1);
34 + arg0 = get_narrower (op0, &unsigned0);
35 + arg1 = get_narrower (op1, &unsigned1);
37 + /* UNS is 1 if the operation to be done is an unsigned one. */
38 + uns = TYPE_UNSIGNED (result_type);
40 final_type = result_type;
42 /* Handle the case that OP0 (or OP1) does not *contain* a conversion
43 Index: testsuite/gcc.c-torture/execute/pr19606.c
44 ===================================================================
45 --- /dev/null 2005-09-01 09:08:28.063949816 -0700
46 +++ gcc/testsuite/gcc.c-torture/execute/pr19606.c 2006-01-15 14:41:56.490361111 -0800
49 + The C front end used to shorten the type of a division even when
50 + the signedness changes. Make sure that won't happen. */
57 + return ((unsigned int) (signed int) a) / 2LL;
63 + return ((unsigned int) (signed int) a) % 5LL;
72 + if (r != ((unsigned int) (signed int) (signed char) -4) / 2LL)
76 + if (r != ((unsigned int) (signed int) (signed char) -4) % 5LL)