https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78622

            Bug ID: 78622
           Summary: [7 Regression] -Wformat-length/-fprintf-return-value
                    incorrect with overflow/wrapping
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The following test case reduced from the one in bug 78586, comment 8, shows the
problem discussed there.  When determining the number of bytes that results
from formatting an argument in some range using a directive of a narrower type
(such as an int using %hhi), the format_integer function in the
gimple-ssa-sprintf pass fails to take into consideration integer overflow (for
signed types) and wrapping (for unsigned types).  When the range of the
argument is such that converting either bound to the type of the directive
overflows or wraps, the pass simply takes the number of bytes that formatting
the overflowed result would produce without considering that a different value
in the same original range can result in a number of bytes that's outside the
overflowed range.

In the test case below,  i's range is determined to be [4105, 4360]. 
Converting the lower bound of the range to char (the type of the %hhi
directive) yields 9, and 4360 yields 8.  Formatting both converted bounds takes
just one byte.  But converting the value 4127 (which is in the [4105, 4360]
range) to char yields 31, which formats in 2 bytes.

$ cat c.c && /build/gcc-git/gcc/xgcc -B /build/gcc-git/gcc -O2 -Wall -Wextra
c.c && ./a.out 
#define FMT "%hhi"
const char *fmt = FMT;

volatile int x = 4127;

int main (void)
{
  int i = x;

  if (i < 4104 || i >= 4360)
    return 0 ;

  ++i;

  int n1 = __builtin_snprintf (0, 0, FMT, i);
  int n2 = __builtin_snprintf (0, 0, fmt, i);

  __builtin_printf ("%i == %i\n", n1, n2);
  if (n1 != n2)
    __builtin_abort ();
}
1 == 2
Aborted (core dumped)

Reply via email to