Add validation and consolidation of fix-it hints

Programming / Compilers / GCC - dmalcolm [138bc75d-0d04-0410-961f-82ee72b054a4] - 26 August 2016 16:25 UTC

The first aspect of this patch is to add some checking of fix-it hints. The idea is to put this checking within the rich_location machinery, rather than requiring every diagnostic to implement it for itself.

The fixits within a rich_location are "atomic": all must be valid for any to be applicable.

We reject any fixits involving locations above LINE_MAP_MAX_LOCATION_WITH_COLS.

There's no guarantee that it's sane to modify a macro, so we reject any fix-its that touch them.

For example, note the attempt to provide a fix-it for the definition of the macro FIELD:

spellcheck-fields-2.c: In function ‘test_macro’: spellcheck-fields-2.c:26:15: error: ‘union u’ has no member named ‘colour’; did you mean ‘color’? #define FIELD colour ^ color spellcheck-fields-2.c:27:15: note: in expansion of macro ‘FIELD’ return ptr->FIELD; ^~~~~

After this patch, the fixit is not displayed:

spellcheck-fields-2.c: In function ‘test_macro’: spellcheck-fields-2.c:26:15: error: ‘union u’ has no member named ‘colour’; did you mean ‘color’? #define FIELD colour ^ spellcheck-fields-2.c:27:15: note: in expansion of macro ‘FIELD’ return ptr->FIELD; ^~~~~

We might want some way for a diagnostic to opt-in to fix-its that affect macros, but for now it's simplest to reject them.

The other aspect of this patch is fix-it consolidation: in some cases neighboring fix-its can be merged. For example, in a diagnostic to modernize old-style struct initializers from:

struct s example = {- foo: 1, + .foo = 1, };

one approach would be to replace the "foo" with ".foo" and the ":" with " =". This would give two "replace" fix-its:

foo: 1,--- FIXIT 1 .foo- FIXIT 2
=

This patch allows them to be consolidated into a single "replace" fix-it:

foo: 1,

.foo =

gcc/ChangeLog:
- diagnostic-show-locus.c (selftest::test_fixit_consolidation): New function. (selftest::diagnostic_show_locus_c_tests): Call it.
- gcc-rich-location.h (gcc_rich_location): Eliminate unused constructor based on source_range.

gcc/testsuite/ChangeLog:
- gcc.dg/spellcheck-fields-2.c (test): Move dg-begin/end-multiline-output within function body. (test_macro): New function.

libcpp/ChangeLog:
- include/line-map.h (rich_location): Eliminate unimplemented constructor based on source_range. (rich_location::get_last_fixit_hint): New method. (rich_location::reject_impossible_fixit): New method. (rich_location): Add fields m_line_table and m_seen_impossible_fixit. (fixit_hint::maybe_append_replace): New pure virtual function. (fixit_insert::maybe_append_replace): New function. (fixit_replace::maybe_append_replace): New function.
- line-map.c (rich_location::rich_location): Initialize m_line_table and m_seen_impossible_fixit. (rich_location::add_fixit_insert): Call reject_impossible_fixit and bail out if true. (column_before_p): New function. (rich_location::add_fixit_replace): Call reject_impossible_fixit and bail out if true. Attempt to consolidate with neighboring fixits. (rich_location::get_last_fixit_hint): New method. (rich_location::reject_impossible_fixit): New method. (fixit_insert::maybe_append_replace): New method. (fixit_replace::maybe_append_replace): New method.

367964f Add validation and consolidation of fix-it hints
gcc/ChangeLog | 8 ++
gcc/diagnostic-show-locus.c | 155 ++++++++++++++++++++++++++++
gcc/gcc-rich-location.h | 5 -
gcc/testsuite/ChangeLog | 6 ++
gcc/testsuite/gcc.dg/spellcheck-fields-2.c | 23 ++++-
libcpp/ChangeLog | 24 +++++
libcpp/include/line-map.h | 19 +++-
libcpp/line-map.c | 136 +++++++++++++++++++++++-
8 files changed, 365 insertions(+), 11 deletions(-)

Upstream: gcc.gnu.org


  • Share