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

            Bug ID: 77672
           Summary: wrong rich location in warning: writing a terminating
                    nul past the end
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

Most -Wformat-length warnings underscore the part of the format string that
causes a buffer overflow.  For example, in the call to sprintf in function f
below the exclamation point (!) is underscored in format character because it's
written past the end of the destination.

However, when the terminating nul character overflows the destination, the
whole format string rather than the (invisible) nul character is underscored. 
The expected output in this case is one of the following (or something
similar):

   sprintf (d, "%-s", "abc");
                   ^
or

   sprintf (d, "%-s", "abc");
               ~~~~^

This appears to be a limitation of the substring_loc class which is capable of
underscoring the whole format string, including the quotes, but which doesn't
make it possible to point the caret at the closing quote.

$ cat v.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -S -Wall
-Wextra -Wpedantic v.c
char d[3];

extern int sprintf (char*, const char*, ...);

void f (void) {
  sprintf (d, "%-s!", "abc");
}

void g (void) {
  sprintf (d, "%-s", "abc");
}

v.c: In function ‘f’:
v.c:6:19: warning: writing format character ‘!’ at offset 3 past the end of the
destination [-Wformat-length=]
   sprintf (d, "%-s!", "abc");
                   ^
v.c:6:3: note: format output 5 bytes into a destination of size 3
   sprintf (d, "%-s!", "abc");
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
v.c: In function ‘g’:
v.c:10:15: warning: writing a terminating nul past the end of the destination
[-Wformat-length=]
   sprintf (d, "%-s", "abc");
               ^~~~~
v.c:10:3: note: format output 4 bytes into a destination of size 3
   sprintf (d, "%-s", "abc");
   ^~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to