This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/49905] Better sanity checking on sprintf src & dest to produce warning for dodgy code ?
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 04 Jul 2016 17:16:29 +0000
- Subject: [Bug middle-end/49905] Better sanity checking on sprintf src & dest to produce warning for dodgy code ?
- Auto-submitted: auto-generated
- References: <bug-49905-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49905
--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #13)
> (In reply to David Binderman from comment #9)
> > I tried a build of the gcc fortran compiler and I found this warning:
> >
> > ../../../src/trunk/libgfortran/intrinsics/date_and_time.c:173:33: warning:
> > ‘%+03d’ directive output truncated while writing ‘9’ bytes into a region of
> > size ‘6’ [-Wformat-length=]
> >
> > Source code is
> >
> > snprintf (zone, ZONE_LEN + 1, "%+03d%02d",
> > values[3] / 60, abs (values[3] % 60));
> >
> > and
> >
> > #define ZONE_LEN 5
> >
> > char zone[ZONE_LEN + 1];
> >
> > While it is clear that the region size of 6 is fine, I can't see where the
> > value
> > of 9 bytes is coming from.
>
> Thanks for the testing! I reproduced the warning the above with -O2 in a
> small test case:
>
> extern int values [4];
> inline int abs(int x) { return x < 0 ? -x : x; }
>
> #define ZONE_LEN 5
>
> char zone[ZONE_LEN + 1];
>
> void f (void)
> {
> __builtin_snprintf (zone, ZONE_LEN + 1, "%+03d%02d",
> values[3] / 60, abs (values[3] % 60));
> }
>
> GCC doesn't know what values[3] evaluates to but since its type is int, the
> Value Range Propagation (VRP) determines that the range of (values[3] / 60)
> is [-35791394, 35791394], and the checker sees that as many as 9 bytes of
> space for the output of any value in that range are required.
But 9 is maximum length just for the %+03d part, %02d with the limited VRP
range is exactly 2 and then the '\0', so that is 12 maximum, 6 minimum.
So printing 9 is just misleading.