On 12/05/2016 08:43 PM, Martin Sebor wrote:

Martin

$ cat b.c && /build/gcc-78622/gcc/xgcc -B /build/gcc-78622/gcc -O2 -S
-Wall -Wextra -Wpedantic b.c
char d[1];

void f (int i)
{
  if (i < 1024 || 1033 < i) i = 1024;

  __builtin_sprintf (d + 1, "%hhi", i);
}

void g (int i)
{
  if (i < 1024 || 3456 < i) i = 1024;

  __builtin_sprintf (d + 1, "%hhi", i);
}

b.c: In function ‘f’:
b.c:7:30: warning: ‘%hhi’ directive writing 1 byte into a region of size
0 [-Wformat-length=]
   __builtin_sprintf (d + 1, "%hhi", i);
                              ^~~~
b.c:7:29: note: directive argument in the range [1024, 1033]
   __builtin_sprintf (d + 1, "%hhi", i);
                             ^~~~~~
b.c:7:3: note: format output 2 bytes into a destination of size 0
   __builtin_sprintf (d + 1, "%hhi", i);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
b.c: In function ‘g’:
b.c:14:30: warning: ‘%hhi’ directive writing between 1 and 4 bytes into
a region of size 0 [-Wformat-length=]
   __builtin_sprintf (d + 1, "%hhi", i);
                              ^~~~
b.c:14:29: note: using the range [0, -128] for directive argument
   __builtin_sprintf (d + 1, "%hhi", i);
                             ^~~~~~
b.c:14:3: note: format output between 2 and 5 bytes into a destination
of size 0
   __builtin_sprintf (d + 1, "%hhi", i);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


gcc-78622.diff


PR middle-end/78622 - [7 Regression] -Wformat-length/-fprintf-return-value 
incorrect with overflow/wrapping

gcc/ChangeLog:

        PR middle-end/78622
        * gimple-ssa-sprintf.c (min_bytes_remaining): Use res.knownrange
        rather than res.bounded.
        (adjust_range_for_overflow): New function.
        (format_integer): Always set res.bounded to true unless either
        precision or width is specified and unknown.
        Call adjust_range_for_overflow.
        (format_directive): Remove vestigial quoting.  Always inform of
        argument value or range when it's available.
        (add_bytes): Correct the computation of boundrange used to
        decide whether a warning is of a "maybe" or "defnitely" kind.

gcc/testsuite/ChangeLog:

        PR middle-end/78622
        * gcc.c-torture/execute/pr78622.c: New test.
        * gcc.dg/tree-ssa/builtin-sprintf-2.c: Remove "benign" undefined
        behavior inadvertently introduced in a previous commit.  Tighten
        up final checking.
        * gcc.dg/tree-ssa/builtin-sprintf-5.c: Rename macros for clarity.
        Add test cases.
        * gcc.dg/tree-ssa/builtin-sprintf-6.c: Add test cases.
        * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Same.
        * gcc.dg/tree-ssa/builtin-sprintf-warn-5.c: Same.
        * gcc.dg/tree-ssa/builtin-sprintf-warn-6.c: Remove xfails and
        add a final optimization check.
        * gcc.dg/tree-ssa/builtin-sprintf.c: Add test cases.

diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 99a635a..a888f55 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -795,6 +795,59 @@ get_width_and_precision (const conversion_spec &spec,
   *pprec = prec;
 }

+/* With the range [*ARGMIN, *ARGMAX] of an integer directive's actual
+   argument, due to the conversion from either *ARGMIN or *ARGMAX to
+   the type of the directive's formal argument it's possible for both
+   to result in the same number of bytes or a range of bytes that's
+   less than the number of bytes that would result from formatting
+   some other value in the range [*ARGMIN, *ARGMAX].  This can be
+   determined by checking for the actual argument being in the range
+   of the type of the directive.  If it isn't it must be assumed to
+   take on the full range of the directive's type.
+   Return true when the range has been adjusted to the range of
+   DIRTYPE, false otherwise.  */
So I think the return value needs a bit of clarification here. Take guidance from our discussion on this thread.

OK with that fixed.

jeff

Reply via email to