[Bug preprocessor/77672] wrong rich location in warning: writing a terminating nul past the end

dmalcolm at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Sep 23 14:31:00 GMT 2016


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

--- Comment #4 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #2)
> I think the general improvement I'm suggesting is to be able to put the
> tilde(s) under or point the caret at any character of the format string,
> including either of the two quotes.

If desired, you can use make_location to construct a location_t for such
situations... though I'm not sure that it makes sense to do so for all of the
different combinations.  I've tried to make class substring_loc provide the API
needed for the common case.

> It's already possible to underscore the whole format string and point the
> caret at any character within in, including the first quote, so it seems
> natural to also point the caret at the last quote.

r240434 updates things so that substring_loc::get_location uses the final quote
for the location of the NUL-terminator character for STRING_CSTs from the C
frontend, so that if that character's index is passed as one of the indices to
substring_loc's constructor, it will handle that (previously, doing so would
lead to substring_loc::get_location, leading to format_warning using the whole
string range, with both start and end quotes).

The output for the test case is now:

$ ./xgcc -B. -c v.c -Wall
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:18: 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");
   ^~~~~~~~~~~~~~~~~~~~~~~~~

Note how in the warning for g it has underlined from the first char through to
the close-quote, with the caret on the s.  This is with:

(gdb) p fmt_loc
$1 = (const substring_loc &) @0x7fffffffda90: {m_fmt_string_loc = 2147483655,
m_string_type = <pointer_type 0x7ffff19e97e0>, 
  m_caret_idx = 2, m_start_idx = 0, m_end_idx = 3}

so it is faithfully printing the idx values it's been provided with by the
diagnostic code.


More information about the Gcc-bugs mailing list