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

            Bug ID: 72858
           Summary: incorrect fixit hints in -Wformat diagnostics
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

With the latest improvements to diagnostics, GCC 7.0 provides fixit hints in
-Wformat diagnostics that suggest the correct format directives where those
specified do not match their arguments.  The hints, however, only include the
length modifier and (what appears to be an approximation of) the conversion
specifier but not any of the flags present in the (incorrect) directive.

That's misleading since it suggests to the user that in addition to replacing
the length modifier they should also avoid using the flags and replace the
conversion specifier they need with a different one.  To avoid giving that
impression the fixit hints should copy the first part of the directive,
including the flags, width, and precision, and use the corresponding conversion
specifier.

The following test case shows some of the problems:

$ cat xyz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -S
-Wformat xyz.c
int f (char *d, long x)
{
  extern int sprintf (char*, const char*, ...);
  sprintf (d, "%-8x", x);
}
xyz.c: In function ‘f’:
xyz.c:4:19: warning: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 3 has type ‘long int’ [-Wformat=]
   sprintf (d, "%-8x", x);
                ~~~^
                %ld

Clang provides the expected hint:

xyz.c:4:23: warning: format specifies type 'unsigned int' but the argument has
      type 'long' [-Wformat]
  sprintf (d, "%-8x", x);
               ~~~~   ^
               %-8lx

Reply via email to