Message ID | 1472065183.28390.4.camel@redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Aug 24, 2016 at 02:59:43PM -0400, David Malcolm wrote: > On Wed, 2016-08-24 at 20:15 +0200, Marek Polacek wrote: > > On Wed, Aug 24, 2016 at 01:57:15PM -0400, David Malcolm wrote: > > > On Wed, 2016-08-24 at 19:43 +0200, Marek Polacek wrote: > > > > This patch adds a fixit hint to -Wlogical-not-parentheses. When > > > > the > > > > LHS > > > > has a location, it prints: > > > > > > > > z.c: In function ‘int foo(int, int)’: > > > > z.c:12:11: warning: logical not is only applied to the left hand > > > > side > > > > of comparison [-Wlogical-not-parentheses] > > > > r += !a == b; > > > > ^~ > > > > z.c:12:8: note: add parentheses around left hand side expression > > > > to > > > > silence this warning > > > > r += !a == b; > > > > ^~ > > > > ( ) > > > > > > > > Bootstrapped/regtested on x86_64-linux and ppc64le-redhat-linux, > > > > ok > > > > for trunk? > > > > > > Thanks for writing new fix-it hints. > > > > > > Can you split this up into two fix-its, one for each parenthesis, > > > at > > > the appropriate locations? A single rich_location (and thus > > > diagnostic) can contain up to 3 fix-it hints at the moment. My > > > hope > > > is that an IDE could, in theory, apply them; right now, the fixit > > > is > > > effectively saying to make this change: > > > > > > - r += !a == b; > > > + r += ( )!a == b; > > > > > > whereas presumably it should be making this change: > > > > > > - r += !a == b; > > > + r += (!a) == b; > > > > True. > > > > > You should be able to access the source end-point of the expression > > > via: > > > get_range_from_loc (line_table, loc).m_finish > > > > I see, thanks. So like in the below? > > Thanks. I didn't fully think through my suggestion, sorry. I think > there's an off-by-one error in the positioning of the closing > parenthesis, though up till now we haven't defined the semantics of > fixits very strongly. > > My interpretation is that an insertion fixit happens immediately > *before* the current content of its column. > > So given these column numbers: > 0000000001111111111 > 1234567890123456789 > r += !aaa == bbb; > > we want to: > (i) insert a '(' immediately before the '! i.e. at column 8 (correct in > the patch), and > (ii) insert a ')' after the "aaa" i.e. immediately before the ' ' after > the "aaa" i.e. at column 12 > > I tried your patch with my "-fdiagnostics-generate-patch" patch, and > the patch it generated for these fixits was: > --- ../../src/gcc/testsuite/c-c++-common/Wlogical-not-parentheses-2.c > +++ ../../src/gcc/testsuite/c-c++-common/Wlogical-not-parentheses-2.c > @@ -8,7 +8,7 @@ > { > int r = 0; > r += (!aaa) == bbb; > - r += !aaa == bbb; /* { dg-warning "logical not is only applied" } */ > + r += (!aa)a == bbb; /* { dg-warning "logical not is only applied" } */ > /* { dg-begin-multiline-output "" } > r += !aaa == bbb; > ^~ > > Note the incorrect: > (!aa)a > rather than: > (!aaa) > > which is consistent with the interpretation above. > > So I think you need to offset that final column by 1, which isn't as > simple as simply adding 1 to the location_t (given packed ranges). > > I believe you need something like: > > next_loc = linemap_position_for_loc_and_offset (line_table, finish, 1) > > I've attached a patch to your patch that does this; with that, the > fixits and > generated patch look like this: Makes sense, thanks. Before I post another patch, should I introduce a helper for this, something like get_one_past_finish or somesuch? Marek
On Wed, 2016-08-24 at 21:50 +0200, Marek Polacek wrote: > On Wed, Aug 24, 2016 at 02:59:43PM -0400, David Malcolm wrote: > > On Wed, 2016-08-24 at 20:15 +0200, Marek Polacek wrote: > > > On Wed, Aug 24, 2016 at 01:57:15PM -0400, David Malcolm wrote: > > > > On Wed, 2016-08-24 at 19:43 +0200, Marek Polacek wrote: > > > > > This patch adds a fixit hint to -Wlogical-not-parentheses. > > > > > When > > > > > the > > > > > LHS > > > > > has a location, it prints: > > > > > > > > > > z.c: In function ‘int foo(int, int)’: > > > > > z.c:12:11: warning: logical not is only applied to the left > > > > > hand > > > > > side > > > > > of comparison [-Wlogical-not-parentheses] > > > > > r += !a == b; > > > > > ^~ > > > > > z.c:12:8: note: add parentheses around left hand side > > > > > expression > > > > > to > > > > > silence this warning > > > > > r += !a == b; > > > > > ^~ > > > > > ( ) > > > > > > > > > > Bootstrapped/regtested on x86_64-linux and ppc64le-redhat > > > > > -linux, > > > > > ok > > > > > for trunk? > > > > > > > > Thanks for writing new fix-it hints. > > > > > > > > Can you split this up into two fix-its, one for each > > > > parenthesis, > > > > at > > > > the appropriate locations? A single rich_location (and thus > > > > diagnostic) can contain up to 3 fix-it hints at the moment. > > > > My > > > > hope > > > > is that an IDE could, in theory, apply them; right now, the > > > > fixit > > > > is > > > > effectively saying to make this change: > > > > > > > > - r += !a == b; > > > > + r += ( )!a == b; > > > > > > > > whereas presumably it should be making this change: > > > > > > > > - r += !a == b; > > > > + r += (!a) == b; > > > > > > True. > > > > > > > You should be able to access the source end-point of the > > > > expression > > > > via: > > > > get_range_from_loc (line_table, loc).m_finish > > > > > > I see, thanks. So like in the below? > > > > Thanks. I didn't fully think through my suggestion, sorry. I > > think > > there's an off-by-one error in the positioning of the closing > > parenthesis, though up till now we haven't defined the semantics of > > fixits very strongly. > > > > My interpretation is that an insertion fixit happens immediately > > *before* the current content of its column. > > > > So given these column numbers: > > 0000000001111111111 > > 1234567890123456789 > > r += !aaa == bbb; > > > > we want to: > > (i) insert a '(' immediately before the '! i.e. at column 8 > > (correct in > > the patch), and > > (ii) insert a ')' after the "aaa" i.e. immediately before the ' ' > > after > > the "aaa" i.e. at column 12 > > > > I tried your patch with my "-fdiagnostics-generate-patch" patch, > > and > > the patch it generated for these fixits was: > > --- ../../src/gcc/testsuite/c-c++-common/Wlogical-not-parentheses > > -2.c > > +++ ../../src/gcc/testsuite/c-c++-common/Wlogical-not-parentheses > > -2.c > > @@ -8,7 +8,7 @@ > > { > > int r = 0; > > r += (!aaa) == bbb; > > - r += !aaa == bbb; /* { dg-warning "logical not is only applied" > > } */ > > + r += (!aa)a == bbb; /* { dg-warning "logical not is only > > applied" } */ > > /* { dg-begin-multiline-output "" } > > r += !aaa == bbb; > > ^~ > > > > Note the incorrect: > > (!aa)a > > rather than: > > (!aaa) > > > > which is consistent with the interpretation above. > > > > So I think you need to offset that final column by 1, which isn't > > as > > simple as simply adding 1 to the location_t (given packed ranges). > > > > I believe you need something like: > > > > next_loc = linemap_position_for_loc_and_offset (line_table, finish, > > 1) > > > > I've attached a patch to your patch that does this; with that, the > > fixits and > > generated patch look like this: > > Makes sense, thanks. Before I post another patch, should I introduce > a helper for this, something like get_one_past_finish or somesuch? I was thinking about maybe: rich_location::add_fixit_insert_after_caret (source_location loc) which would add it immediately after the *caret* location of loc - as opposed to after the *finish* location of loc, or maybe just: rich_location::add_fixit_insert_after (source_location loc) which would take into account the finish location of loc. Having a helper in rich_location for this would be good, for protecting against cases where some of the tokens are in a macro expansion, and others aren't (I think fix-its within a rich_location ought to be atomic: if some can't be applied, none should be). I'd rather have the rich_location machinery care about these awkward issues in one place, rather than force every diagnostic to do it. I already have the beginnings of some fixit validation code written (but not posted), so maybe you should go ahead and post the patch as-is, and we can move the relevant parts into a helper as a followup? Dave
From 77a245f07749c2b175e3f15186fe1fe995b2a33d Mon Sep 17 00:00:00 2001 From: David Malcolm <dmalcolm@redhat.com> Date: Wed, 24 Aug 2016 15:19:49 -0400 Subject: [PATCH] Fix off-by-one column issue in fixit --- gcc/c-family/c-common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 1059466..001070d 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1506,7 +1506,10 @@ warn_logical_not_parentheses (location_t location, enum tree_code code, location_t lhs_loc = EXPR_LOCATION (lhs); rich_location richloc (line_table, lhs_loc); richloc.add_fixit_insert (lhs_loc, "("); - richloc.add_fixit_insert (get_finish (lhs_loc), ")"); + location_t finish = get_finish (lhs_loc); + location_t next_loc + = linemap_position_for_loc_and_offset (line_table, finish, 1); + richloc.add_fixit_insert (next_loc, ")"); inform_at_rich_loc (&richloc, "add parentheses around left hand side " "expression to silence this warning"); } -- 1.8.5.3