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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2016-09-27
                 CC|                            |msebor at gcc dot gnu.org
     Ever confirmed|0                           |1
      Known to fail|                            |7.0

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Confirmed.  The warning is a false positive (and with -Wformat-length=2 is
issued for both functions).  The output of the -ftree-dump-vrp option shows
that the Value Range Propagation pass correctly determines each variable's
range to be [0, 999] but, as the note printed after the warning indicates, the
range made available to the gimple-ssa-sprintf pass (via the get_range_info
API) is that of unsigned int.

Unfortunately, this is a general limitation in the current implementation of
ranges in GCC and not something that can be fixed in the warning pass.  A new
implementation of VRP is in progress but it doesn't seem likely that it will
make it into GCC 7.

$ cat zzz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -O2
-O2 -S -Wall -Wformat-length=2 zzz.c
int snprintf (char*, __SIZE_TYPE__, const char*, ...);

void foo(unsigned j, char *p)
{
    if(j > 999)
        return;
    snprintf(p, 4, "%3u", j);
}

void bar(int j, char *p)
{
    const unsigned k = (unsigned) j;
    if(k > 999)
        return;
    snprintf(p, 4, "%3u", k);
}
zzz.c: In function ‘foo’:
zzz.c:7:21: warning: ‘%3u’ directive output may be truncated writing between 3
and 10 bytes into a region of size 4 [-Wformat-length=]
     snprintf(p, 4, "%3u", j);
                     ^~~
zzz.c:7:20: note: using the range [‘1u’, ‘2147483648u’] for directive argument
     snprintf(p, 4, "%3u", j);
                    ^~~~~
zzz.c:7:5: note: format output between 4 and 11 bytes into a destination of
size 4
     snprintf(p, 4, "%3u", j);
     ^~~~~~~~~~~~~~~~~~~~~~~~
zzz.c: In function ‘bar’:
zzz.c:15:21: warning: ‘%3u’ directive output may be truncated writing between 3
and 10 bytes into a region of size 4 [-Wformat-length=]
     snprintf(p, 4, "%3u", k);
                     ^~~
zzz.c:15:20: note: directive argument in the range [0u, 4294967295u]
     snprintf(p, 4, "%3u", k);
                    ^~~~~
zzz.c:15:5: note: format output between 4 and 11 bytes into a destination of
size 4
     snprintf(p, 4, "%3u", k);
     ^~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to