re PR c/19606 (wrong code for arith.expr: (((unsigned int)(signed int) a ) / 2LL) with signed char a=-4)

gcc/
	PR c/19606.
	* c-typeck.c (build_binary_op): Perform implicit casts of
	operands before shortening them.

gcc/testsuite/
	PR c/19606.
	* gcc.c-torture/execute/pr19606.c: New.

From-SVN: r110321
This commit is contained in:
Kazu Hirata 2006-01-28 05:19:44 +00:00 committed by Kazu Hirata
parent dadd8a3feb
commit e6620e8637
4 changed files with 72 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2006-01-28 Kazu Hirata <kazu@codesourcery.com>
PR c/19606.
* c-typeck.c (build_binary_op): Perform implicit casts of
operands before shortening them.
2006-01-27 H.J. Lu <hongjiu.lu@intel.com>
* df-scan.c (df_record_entry_block_defs): Check if

View File

@ -8101,12 +8101,35 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
if (shorten && none_complex)
{
int unsigned0, unsigned1;
tree arg0 = get_narrower (op0, &unsigned0);
tree arg1 = get_narrower (op1, &unsigned1);
/* UNS is 1 if the operation to be done is an unsigned one. */
int uns = TYPE_UNSIGNED (result_type);
tree arg0, arg1;
int uns;
tree type;
/* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
excessive narrowing when we call get_narrower below. For
example, suppose that OP0 is of unsigned int extended
from signed char and that RESULT_TYPE is long long int.
If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
like
(long long int) (unsigned int) signed_char
which get_narrower would narrow down to
(unsigned int) signed char
If we do not cast OP0 first, get_narrower would return
signed_char, which is inconsistent with the case of the
explicit cast. */
op0 = convert (result_type, op0);
op1 = convert (result_type, op1);
arg0 = get_narrower (op0, &unsigned0);
arg1 = get_narrower (op1, &unsigned1);
/* UNS is 1 if the operation to be done is an unsigned one. */
uns = TYPE_UNSIGNED (result_type);
final_type = result_type;
/* Handle the case that OP0 (or OP1) does not *contain* a conversion

View File

@ -1,3 +1,8 @@
2006-01-28 Kazu Hirata <kazu@codesourcery.com>
PR c/19606.
* gcc.c-torture/execute/pr19606.c: New.
2006-01-27 Carlos O'Donell <carlos@codesourcery.com>
* gcc.dg/pragma-re-4.c: New test.

View File

@ -0,0 +1,34 @@
/* PR c/19606
The C front end used to shorten the type of a division to a type
that does not preserve the semantics of the original computation.
Make sure that won't happen. */
signed char a = -4;
int
foo (void)
{
return ((unsigned int) (signed int) a) / 2LL;
}
int
bar (void)
{
return ((unsigned int) (signed int) a) % 5LL;
}
int
main (void)
{
int r;
r = foo ();
if (r != ((unsigned int) (signed int) (signed char) -4) / 2LL)
abort ();
r = bar ();
if (r != ((unsigned int) (signed int) (signed char) -4) % 5LL)
abort ();
exit (0);
}