Beyond that, the range normally works fine, except when macros
are involved like they are in my tests. You can see the effect
in the range.out file. (This works without your patch but it
could very well be because I didn't set it up right.)
Sadly I can't figure out what's going wrong - but the code's changed a
lot at my end since then. Sorry.
I have integrated the latest (already committed) version of your
patch into my -Wformat-length patch. Everything (well almost)
works and I get nice ranges for the format string and for (some)
arguments.
I was surprised at how long it took me to switch from the previous
implementation (also copied from c-format.c) to this new API. As
before, I had to copy bits and pieces of code from other parts of
the compiler to get it to work. I was also surprised at how complex
making use of it is. It added 130 lines of code to the pass, which
is 40 more than what I had before. It seems that the
format_warning_at_substring function from c-format.c (perhaps
generalized and with some reasonable defaults hardcoded) should
be defined where other parts of GCC (including the middle end)
can reuse it.
I ran into a few minor glitches while testing it and I raised
the following bugs for two of them:
77328 - incorrect caret location in -Wformat calling printf
via a macro (this was pre-existing)
77331 - incorrect range location in -Wformat with a concatenated
format literal (this is new)
The third issue seems like a limitation that I should be able to
overcome but I couldn't figure out how using the new API. The
problem is that there doesn't seem to be a way to point the caret
at the closing quote of a string, like for example in the following
test. Even though by default the whole string is underlined (and
the caret points to the opening quote), there doesn't seem to be
a way to specify a range where the caret points to the other quote.
It's no big deal and I only noticed it because one of my tests
started failing, but it seems like it should be possible.
$ cat t.c && /build/gcc-49905/gcc/xgcc -B /build/gcc-49905/gcc -S
-Wformat t.c
char d [2];
void f (void)
{
__builtin_sprintf (d, "%sX", "1");
}
t.c: In function āfā:
t.c:5:25: warning: writing a terminating nul past the end of the
destination [-Wformat-length=]
__builtin_sprintf (d, "%sX", "1");
^~~~~
What I would like to see is similar to what I get when one of
the format string characters is written past the end:
t.c:5:30: warning: writing format character āZā at offset 4 past the end
of the destination [-Wformat-length=]
__builtin_sprintf (d, "%sXYZ", "");
^
Martin