On Thu, Feb 02, 2017 at 05:31:19PM -0700, Martin Sebor wrote:
> index 9e099f0..84dd3671 100644
> --- a/gcc/gimple-ssa-sprintf.c
> +++ b/gcc/gimple-ssa-sprintf.c
> @@ -1242,6 +1242,10 @@ format_integer (const directive &dir, tree arg)
>         of the format string by returning [-1, -1].  */
>      return fmtresult ();
>  
> +  /* The adjustment to add to the MIN counter when computing the LIKELY
> +     counter for arguments with unknown values.  */
> +  unsigned likely_adjust = 0;
> +
>    fmtresult res;
>  
>    /* Using either the range the non-constant argument is in, or its
> @@ -1273,6 +1277,15 @@ format_integer (const directive &dir, tree arg)
>  
>         res.argmin = argmin;
>         res.argmax = argmax;
> +
> +       /* Set the adjustment for an argument whose range includes
> +          zero since that doesn't include the octal or hexadecimal
> +          base prefix.  */
> +       wide_int wzero = wi::zero (wi::get_precision (min));
> +       if (maybebase
> +           && wi::le_p (min, wzero, SIGNED)
> +           && wi::le_p (wzero, max, SIGNED))
> +         likely_adjust = base == 8 ? 1 : base == 16 ? 2 : 0;
>       }
>        else if (range_type == VR_ANTI_RANGE)
>       {
> @@ -1311,11 +1324,14 @@ format_integer (const directive &dir, tree arg)
>        or one whose value range cannot be determined, create a T_MIN
>        constant if the argument's type is signed and T_MAX otherwise,
>        and use those to compute the range of bytes that the directive
> -      can output.  When precision may be zero, use zero as the minimum
> -      since it results in no bytes on output (unless width is specified
> -      to be greater than 0).  */
> -      bool zero = dir.prec[0] <= 0 && dir.prec[1] >= 0;
> -      argmin = build_int_cst (argtype, !zero);
> +      can output.  */
> +      argmin = integer_zero_node;
> +
> +      /* Set the adjustment for an argument whose range includes
> +      zero since that doesn't include the octal or hexadecimal
> +      base prefix.  */
> +      if (maybebase)
> +     likely_adjust = base == 8 ? 1 : base == 16 ? 2 : 0;

This is another sign why the patch I've posted is desirable.  Now you have
to tweak several places, with the patch just one, you have a final range
and you can check whether it includes zero or not.

wi::le_p (wzero, max, SIGNED) is !wi::neg_p (max) I think.

That said, adding something to res.range.min looks wrong to me, you don't
know without more analysis whether actually the length for 0 and length for
say 1 or -1 isn't the same.
Consider %#x where indeed 0 is 2 byte shorter than 1, but say %#3x where
it is the same length, so if you still add your likely_adjust of 2 to that,
the res.range.likely value will be suddenly 5 instead of correct 3.

Easier would be to see if 0 is in the range, see if 1 is also in the range
and set res.range.likely to the length of 1, or, if 0 is in the range, 1
is not but -1 is, to that of -1 or something like that.

        Jakub

Reply via email to