Jakub Jelinek <ja...@redhat.com> writes:
> @@ -2036,11 +2075,20 @@ wi::lrshift_large (HOST_WIDE_INT *val, c
>                  unsigned int xlen, unsigned int xprecision,
>                  unsigned int precision, unsigned int shift)
>  {
> -  unsigned int len = rshift_large_common (val, xval, xlen, xprecision, 
> shift);
> +  /* Work out how many blocks are needed to store the significant bits
> +     (excluding the upper zeros or signs).  */
> +  unsigned int blocks_needed = BLOCKS_NEEDED (xprecision - shift);
> +  unsigned int len = blocks_needed;
> +  if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS)
> +      && len > xlen
> +      && xval[xlen - 1] >= 0)
> +    len = xlen;

I think here too it would be worth dropping the:

  UNLIKELY (len > WIDE_INT_MAX_INL_ELTS)

part of the condition, since presumably the change should be safe
regardless of that.

> +
> +  rshift_large_common (val, xval, xlen, shift, len);
>  
>    /* The value we just created has precision XPRECISION - SHIFT.
>       Zero-extend it to wider precisions.  */
> -  if (precision > xprecision - shift)
> +  if (precision > xprecision - shift && len == blocks_needed)
>      {
>        unsigned int small_prec = (xprecision - shift) % 
> HOST_BITS_PER_WIDE_INT;
>        if (small_prec)
> @@ -2063,11 +2111,18 @@ wi::arshift_large (HOST_WIDE_INT *val, c
>                  unsigned int xlen, unsigned int xprecision,
>                  unsigned int precision, unsigned int shift)
>  {
> -  unsigned int len = rshift_large_common (val, xval, xlen, xprecision, 
> shift);
> +  /* Work out how many blocks are needed to store the significant bits
> +     (excluding the upper zeros or signs).  */
> +  unsigned int blocks_needed = BLOCKS_NEEDED (xprecision - shift);
> +  unsigned int len = blocks_needed;
> +  if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS) && len > xlen)
> +    len = xlen;
> +

Same here.

OK for thw wide-int parts with those changes.

Thanks,
Richard

Reply via email to