From 2f35df8c1423f258a7a61fb1e0eba242b5033b5a Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sat, 26 Jan 2008 11:26:36 +0000 Subject: re PR c++/34235 (short variable cast to unsigned int fails to right shift as unsigned) 2008-01-26 Richard Guenther PR c++/34235 * typeck.c (build_binary_op): Remove code to shorten compares. * g++.dg/torture/pr34235.C: New testcase. From-SVN: r131862 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/typeck.c | 45 ---------------------------------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/torture/pr34235.C | 11 +++++++++ 4 files changed, 21 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr34235.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1f05c68..1e3f462 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-01-26 Richard Guenther + + PR c++/34235 + * typeck.c (build_binary_op): Remove code to shorten compares. + 2008-01-25 Richard Guenther PR c++/33887 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d75f4e4..d86adcd 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3065,10 +3065,6 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, Also implies COMMON. */ int short_compare = 0; - /* Nonzero if this is a right-shift operation, which can be computed on the - original short and then promoted if the operand is a promoted short. */ - int short_shift = 0; - /* Nonzero means set RESULT_TYPE to the common type of the args. */ int common = 0; @@ -3270,8 +3266,6 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, warning (0, "right shift count is negative"); else { - if (! integer_zerop (op1)) - short_shift = 1; if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) warning (0, "right shift count >= width of type"); } @@ -3686,45 +3680,6 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, result_type = type; } - /* Shifts can be shortened if shifting right. */ - - if (short_shift) - { - int unsigned_arg; - tree arg0 = get_narrower (op0, &unsigned_arg); - - final_type = result_type; - - if (arg0 == op0 && final_type == TREE_TYPE (op0)) - unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0)); - - if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) - /* We can shorten only if the shift count is less than the - number of bits in the smaller type size. */ - && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0 - /* If arg is sign-extended and then unsigned-shifted, - we can simulate this with a signed shift in arg's type - only if the extended result is at least twice as wide - as the arg. Otherwise, the shift could use up all the - ones made by sign-extension and bring in zeros. - We can't optimize that case at all, but in most machines - it never happens because available widths are 2**N. */ - && (!TYPE_UNSIGNED (final_type) - || unsigned_arg - || (((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0))) - <= TYPE_PRECISION (result_type)))) - { - /* Do an unsigned shift if the operand was zero-extended. */ - result_type - = c_common_signed_or_unsigned_type (unsigned_arg, - TREE_TYPE (arg0)); - /* Convert value-to-be-shifted to that type. */ - if (TREE_TYPE (op0) != result_type) - op0 = cp_convert (result_type, op0); - converted = 1; - } - } - /* Comparison operations are shortened too but differently. They identify themselves by setting short_compare = 1. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 143ae0d..6535805 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-01-26 Richard Guenther + + PR c++/34235 + * g++.dg/torture/pr34235.C: New testcase. + 2008-01-26 Richard Sandiford * g++.dg/tree-ssa/ivopts-1.C: XFAIL for MIPS too. diff --git a/gcc/testsuite/g++.dg/torture/pr34235.C b/gcc/testsuite/g++.dg/torture/pr34235.C new file mode 100644 index 0000000..5f05841 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr34235.C @@ -0,0 +1,11 @@ +/* { dg-do run } */ + +extern "C" void abort (void); +int main() +{ + short x = -1; + unsigned int c = ((unsigned int)x) >> 1; + if (c != 0x7fffffff) + abort(); + return 0; +} -- cgit v1.1