https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77721
Martin Sebor 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 ---
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);
^~~~