This is the mail archive of the
`gcc@gcc.gnu.org`
mailing list for the GCC project.

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |

Other format: | [Raw text] |

*From*: "Hartmut Penner" <HPENNER at de dot ibm dot com>*To*: gcc at gcc dot gnu dot org*Cc*: "Torsten Hendel" <HENDELT at de dot ibm dot com>*Date*: Fri, 8 Mar 2002 09:31:52 +0100*Subject*: Bug in fold-const.c

unsigned short c = 0x8000; main() { if ((c-0x8000) < 0 || (c-0x8000) >0x7fff) abort(); } When compiling this little testcase with any gcc version (2.95, 3.1...) without optimization anything works fine. By turning on optimization it will abort. I debugged it a bit and found out, that the bug is probably in the function make_range in fold-const.c Take a look in the following code from make_range line 3027: /* If we're converting from an unsigned to a signed type, we will be doing the comparison as unsigned. The tests above have already verified that LOW and HIGH are both positive. So we have to make sure that the original unsigned value will be interpreted as positive. */ -> (c-0x8000) < 0) -> minus_expr exp is done integer signed mode, TREE_UNSIGNED (type) is true (type of c) ->n_low is 0x8000 if (TREE_UNSIGNED (type) && ! TREE_UNSIGNED (TREE_TYPE (exp))) { tree equiv_type = type_for_mode (TYPE_MODE (type), 1); tree high_positive; /* A range without an upper bound is, naturally, unbounded. Since convert would have cropped a very large value, use the max value for the destination type. */ high_positive = TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type) : TYPE_MAX_VALUE (type); -> high positive is 0xffff high_positive = fold (build (RSHIFT_EXPR, type, convert (type, high_positive), convert (type, integer_one_node))); ->high_posotive is converted to 0x7fff /* If the low bound is specified, "and" the range with the range for which the original unsigned value will be positive. */ if (low != 0) { if (! merge_ranges (&n_in_p, &n_low, &n_high, 1, n_low, n_high, 1, convert (type, integer_zero_node), high_positive)) break; in_p = (n_in_p == in_p); } else { /* Otherwise, "or" the range with the range of the input that will be interpreted as negative. */ if (! merge_ranges (&n_in_p, &n_low, &n_high, 0, n_low, n_high, 1, convert (type, integer_zero_node), high_positive)) break; in_p = (in_p != n_in_p); } ->n_low is 0, n_high is 0, ->>> n_low should be 0x8000, n_high should be 0xffff } My first guess to fix this would be to something like this if (TREE_PRECISION (type) >= TREE_PRECISION (TREE_TYPE (exp))) high_positive = fold (build (RSHIFT_EXPR, type, convert (type, high_positive), convert (type, integer_one_node))); Mit freundlichem Gruß / Best regards, Hartmut Penner GCC for S/390 Development Internet Mail Address : hpenner@de.ibm.com Tel: (49)-7031-16-4364

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |