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