On Mon, 2016-08-22 at 21:25 -0600, Martin Sebor wrote:
> > > 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'm guessing that it was difficult because the most useful parts are
currently in c-format.c, whereas your code is in the middle-end.

Is the latest version of your patch posted somewhere where I can see
it?

The substring_loc class should probably be moved from c-family to gcc
also.   We might need a langhook to support that though (not sure yet).

I'd be up for doing these moves (maybe moving
 format_warning_at_substring to diagnostic.h/c), but I'd prefer to see
your patch first.


> 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", "");
>                                ^
> 

So would you like the output to look like this:


Option (a): underline whole string, with caret at close-quote

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");
                           ~~~~^

or like this:

Option (b): just the close-quote

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");
                               ^
?

(do you also emit a note/inform showing the size of d?)

What API are you using to emit the warning?  Given the location of the
string as a whole expressed as a location_t, you can probably do
something like this:

location_t
option_a (location_t string_as_a_whole_loc)
{
  source_range src_range
    = get_range_from_loc (line_table, string_as_a_whole_loc);
  
  return make_location (src_range.m_finish, /* caret */
                        src_range.m_start, src_range.m_finish);
}

location_t
option_b (location_t string_as_a_whole_loc)
{
  source_range
src_range
    = get_range_from_loc (line_table, string_as_a_whole_loc);
 
  return src_range.m_finish;
}

(these could be added to libcpp)

but I get the impression you want something like this integrated into
the format_warning or substring_loc APIs (and it's hard to tell without
seeing your patch).

Hope this is helpful
Dave

Reply via email to