On Mon, Jun 1, 2015 at 10:06 PM, Richard Sandiford <rdsandif...@googlemail.com> wrote: > Marek Polacek <pola...@redhat.com> writes: >> + /* Left-hand operand must be signed. */ >> + if (TYPE_UNSIGNED (type0)) >> + return false; >> + >> + /* Compute the result in infinite precision math (sort of). */ >> + widest_int w = wi::lshift (wi::to_widest (op0), wi::to_widest (op1)); >> + unsigned int min_prec = wi::min_precision (w, SIGNED); >> + /* Watch out for shifting a negative value. */ >> + tree r = wide_int_to_tree (tree_int_cst_sgn (op0) >= 0 >> + ? unsigned_type_for (type0) >> + : type0, w); >> + bool overflowed = wi::cmps (w, wi::to_widest (r)); >> + if (overflowed && c_inhibit_evaluation_warnings == 0) >> + warning_at (loc, OPT_Wshift_overflow, >> + "result of %qE requires %u bits to represent, " >> + "but %qT only has %u bits", >> + build2_loc (loc, LSHIFT_EXPR, type0, op0, op1), >> + min_prec, type0, TYPE_PRECISION (type0)); >> + >> + return overflowed; > > Yeah, this "sort of" is a bit worrying :-) Especially as the number > of bits in a widest_int depends on the number of bits in the target's > widest integer mode. E.g. for i386 it's forced to 128, but for ARM > it's 512 (IIRC). > > Could you do the check based on the wi::min_precision of the unshifted > value? I.e. see whether adding the shift amount to that gives a value > greater than type's precision.
You could always use a FIXED_WIDE_INT like VRP does for its overflow detection stuff. Richard. > Thanks, > Richard