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

            Bug ID: 72857
           Summary: incorrect caret location in -Wformat for width and
                    precision given by asterisk
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

In -Wformat diagnostics, GCC 6.1 (and 7.0, likely prior to r239260) would, for
the most part, point the caret to the component of a format directive that it
complained about.  For example, in the program below, it would point at the
asterisk corresponding to the problem width or precision:

$ cat xyz.c && gcc -S -Wformat xyz.c
int f (char *d, long i)
{
  __builtin_sprintf (d, "%*ld", i, i);
  __builtin_sprintf (d, "%.*ld", i, i);
}
xyz.c: In function ‘f’:
xyz.c:3:27: warning: field width specifier ‘*’ expects argument of type ‘int’,
but argument 3 has type ‘long int’ [-Wformat=]
   __builtin_sprintf (d, "%*ld", i, i);
                           ^
xyz.c:4:28: warning: field precision specifier ‘.*’ expects argument of type
‘int’, but argument 3 has type ‘long int’ [-Wformat=]
   __builtin_sprintf (d, "%.*ld", i, i);
                            ^

The current trunk of GCC 7.0 has lost that feature and the caret instead points
to the end of the format directive:

xyz.c: In function ‘f’:
xyz.c:3:29: warning: field width specifier ‘*’ expects argument of type ‘int’,
but argument 3 has type ‘long int’ [-Wformat=]
   __builtin_sprintf (d, "%*ld", i, i);
                          ~~~^
xyz.c:4:30: warning: field precision specifier ‘.*’ expects argument of type
‘int’, but argument 3 has type ‘long int’ [-Wformat=]
   __builtin_sprintf (d, "%.*ld", i, i);
                          ~~~~^

This is a minor problem (distinguishing width from precision by including the
period in the latter helps), but it is a regression nonetheless.

Below is what Clang outputs for comparison.  (Underlining the argument
corresponding to the asterisk for the width or precision seems like an
especially nice touch.)

xyz.c:3:18: warning: field width should have type 'int', but argument has type
      'long' [-Wformat]
  sprintf (d, "%*ld", i, i);
               ~~^~   ~
xyz.c:4:18: warning: field precision should have type 'int', but argument has
      type 'long' [-Wformat]
  sprintf (d, "%.*ld", i, i);
               ~~^~~   ~

Reply via email to