Marek Polacek <[email protected]> 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.

Thanks,
Richard

Reply via email to