On 02/25/2017 03:46 PM, Martin Sebor wrote:
In an arithmetic directive with the width or precision specified
by an argument to the asterisk (e.g., "%*x") and where the argument
range is unknown, for the purposes of the return value optimization
the pass must assume it's potentially as large as INT_MAX.  But for
the purposes of issuing a warning, that assumption leads to false
positives because the value of the argument can and in reality
usually is much smaller.

The attached patch adjusts the checker to use the lower bound in
this case to avoid these false positives.  It does that for both
integer and floating directives (for the latter it uses the lesser
of 3 and the lower bound in this case).

In addition, the patch corrects the handling of the pound flag ('#')
in "%#.*g" directives which makes it keep as many trailing zeros after
the radix character as specified by the precision.  (Without the '#',
"%.*g" trims trailing zeros.)

Martin



gcc-79692.diff


PR middle-end/79692 - [7 Regression] -Wformat-overflow false positive

gcc/ChangeLog:

        PR c/79692
        * gimple-ssa-sprintf.c
        (directive::known_width_and_precision): New function.
        (format_integer): Use it.
        (get_mpfr_format_length): Consider the full range of precision
        when computing %g output with the # flag.  Set the likely byte
        count to 3 rather than 1 when precision is indeterminate.
        (format_floating): Correct the lower bound of precision.

gcc/testsuite/ChangeLog:

        PR c/79692
        * gcc.dg/tree-ssa/builtin-sprintf-2.c: Add test cases.
        * gcc.dg/tree-ssa/builtin-sprintf-warn-10.c: Correct %#g.
        * gcc.dg/tree-ssa/builtin-sprintf-warn-15.c: New test.

So in some cases you use

+  /* For an indeterminate precision the lower bound must be assumed
+     to be zero.  */
+  if (prec[0] < 0 && prec[1] >= 0)

Note prec[1] >= 0

In other cases you have:

+       /* The minimum output with unknown precision is a single byte
+          (e.g., "0") but the more likely output is 3 bytes ("0.0").  */
+       if (dir.prec[0] < 0 && dir.prec[1] > 0)

Note  dir.prec[1] > 0

Shouldn't one of those be changed to be consistent with the other?

Similarly in known_width_and_precision. Please review the patch to ensure that we're as consistent as possible for these tests.


OK after doing that review and making any necessary trivial adjustments.

Jeff


Reply via email to