From b09649fdc609c79ea5acb9668636c7d8a5f64a7c Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 9 Jun 2017 20:57:38 +0000 Subject: [PATCH] Add support for mutually-incompatible fix-it hints This patch adds a method: rich_location::fixits_cannot_be_auto_applied for ensuring that mutually-incompatible fix-its hints don't lead to insane output from -fdiagnostics-generate-patch. Fix-it hints within such rich_location instances are printed as normal by diagnostic_show_locus, but don't affect the output of -fdiagnostics-generate-patch. gcc/ChangeLog: * diagnostic.c (diagnostic_report_diagnostic): Only add fixits to the edit_context if they can be auto-applied. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-show-locus-bw.c (test_mutually_exclusive_suggestions): New test function. * gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c (test_mutually_exclusive_suggestions): New test function. * gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c (test_mutually_exclusive_suggestions): New test function. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (test_show_locus): Add special-case for "test_mutually_exclusive_suggestions". libcpp/ChangeLog: * include/line-map.h (rich_location::fixits_cannot_be_auto_applied): New method. (rich_location::fixits_can_be_auto_applied_p): New accessor. (rich_location::m_fixits_cannot_be_auto_applied): New field. * line-map.c (rich_location::rich_location): Initialize new field. From-SVN: r249081 --- gcc/ChangeLog | 5 ++++ gcc/diagnostic.c | 3 ++- gcc/testsuite/ChangeLog | 12 ++++++++++ .../plugin/diagnostic-test-show-locus-bw.c | 20 ++++++++++++++++ ...iagnostic-test-show-locus-generate-patch.c | 13 ++++++++++ ...gnostic-test-show-locus-parseable-fixits.c | 14 +++++++++++ .../diagnostic_plugin_test_show_locus.c | 24 +++++++++++++++++++ libcpp/ChangeLog | 8 +++++++ libcpp/include/line-map.h | 22 +++++++++++++++++ libcpp/line-map.c | 3 ++- 10 files changed, 122 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9cbae2a09ef..4ab6f8a168a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-06-09 David Malcolm + + * diagnostic.c (diagnostic_report_diagnostic): Only add fixits + to the edit_context if they can be auto-applied. + 2017-06-9 Ian Lance Taylor * opts.c (finish_options): If -fsplit-stack, disable implicit diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 158519606f8..bbf5f5ce7a6 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -986,7 +986,8 @@ diagnostic_report_diagnostic (diagnostic_context *context, diagnostic->x_data = NULL; if (context->edit_context_ptr) - context->edit_context_ptr->add_fixits (diagnostic->richloc); + if (diagnostic->richloc->fixits_can_be_auto_applied_p ()) + context->edit_context_ptr->add_fixits (diagnostic->richloc); context->lock--; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05a5827dca7..cc36d7a35b6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2017-06-09 David Malcolm + + * gcc.dg/plugin/diagnostic-test-show-locus-bw.c + (test_mutually_exclusive_suggestions): New test function. + * gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c + (test_mutually_exclusive_suggestions): New test function. + * gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c + (test_mutually_exclusive_suggestions): New test function. + * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c + (test_show_locus): Add special-case for + "test_mutually_exclusive_suggestions". + 2017-06-09 Ian Lance Taylor * gcc.dg/tree-prof/split-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c index 25b9d6cb382..100fa380cd7 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c @@ -269,3 +269,23 @@ void test_fixit_insert_newline (void) { dg-end-multiline-output "" } */ #endif } + +/* Unit test for mutually-exclusive suggestions. */ + +void test_mutually_exclusive_suggestions (void) +{ +#if 0 + original; /* { dg-warning "warning 1" } */ +/* { dg-warning "warning 2" "" { target *-*-* } .-1 } */ +/* { dg-begin-multiline-output "" } + original; + ^~~~~~~~ + replacement_1 + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + original; + ^~~~~~~~ + replacement_2 + { dg-end-multiline-output "" } */ +#endif +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c index 4522dcd350e..f1963dd20c1 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c @@ -51,6 +51,19 @@ void test_fixit_insert_newline (void) #endif } +/* Unit test for mutually-exclusive suggestions. */ + +void test_mutually_exclusive_suggestions (void) +{ +#if 0 + original; /* { dg-warning "warning 1" } */ +/* { dg-warning "warning 2" "" { target *-*-* } .-1 } */ +/* We should not print the mutually-incompatible fix-it hints within + the generated patch; they are not listed in the big expected + multiline output below. */ +#endif +} + /* Verify the output from -fdiagnostics-generate-patch. We expect a header, containing the filename. This is the absolute path, so we can only capture it via regexps. */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c index 25a7c3c5072..16162baeb7e 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c @@ -55,3 +55,17 @@ void test_fixit_insert_newline (void) /* { dg-regexp "fix-it:.*\\{52:1-52:1\\}:.*\\n" } */ #endif } + +/* Unit test for mutually-exclusive suggestions. */ + +void test_mutually_exclusive_suggestions (void) +{ +#if 0 + original; /* { dg-warning "warning 1" } */ +/* { dg-warning "warning 2" "" { target *-*-* } .-1 } */ +/* We should print the mutually-incompatible fix-it hints within + -fdiagnostics-parseable-fixits; verify that they are printed. */ +/* { dg-regexp "fix-it:.*\\{64:3-64:11}:.*\\n" } */ +/* { dg-regexp "fix-it:.*\\{64:3-64:11}:.*\\n" } */ +#endif +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index 6afb58414f0..0a8eeba1846 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -306,6 +306,30 @@ test_show_locus (function *fun) warning_at_rich_loc (&richloc, 0, "example of a replacement hint"); } + if (0 == strcmp (fnname, "test_mutually_exclusive_suggestions")) + { + const int line = fnstart_line + 2; + location_t start = get_loc (line, 2); + location_t finish = get_loc (line, 9); + source_range src_range; + src_range.m_start = start; + src_range.m_finish = finish; + + { + rich_location richloc (line_table, make_location (start, start, finish)); + richloc.add_fixit_replace (src_range, "replacement_1"); + richloc.fixits_cannot_be_auto_applied (); + warning_at_rich_loc (&richloc, 0, "warning 1"); + } + + { + rich_location richloc (line_table, make_location (start, start, finish)); + richloc.add_fixit_replace (src_range, "replacement_2"); + richloc.fixits_cannot_be_auto_applied (); + warning_at_rich_loc (&richloc, 0, "warning 2"); + } + } + /* Example of two carets where both carets appear to have an off-by-one error appearing one column early. Seen with gfortran.dg/associate_5.f03. diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 8032d7cde99..13a33c302f6 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,11 @@ +2017-06-09 David Malcolm + + * include/line-map.h + (rich_location::fixits_cannot_be_auto_applied): New method. + (rich_location::fixits_can_be_auto_applied_p): New accessor. + (rich_location::m_fixits_cannot_be_auto_applied): New field. + * line-map.c (rich_location::rich_location): Initialize new field. + 2017-06-05 David Malcolm * include/cpplib.h (struct cpp_callbacks): Add "comment" diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 90d65d746ab..be3041df2be 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -1663,6 +1663,27 @@ class rich_location fixit_hint *get_last_fixit_hint () const; bool seen_impossible_fixit_p () const { return m_seen_impossible_fixit; } + /* Set this if the fix-it hints are not suitable to be + automatically applied. + + For example, if you are suggesting more than one + mutually exclusive solution to a problem, then + it doesn't make sense to apply all of the solutions; + manual intervention is required. + + If set, then the fix-it hints in the rich_location will + be printed, but will not be added to generated patches, + or affect the modified version of the file. */ + void fixits_cannot_be_auto_applied () + { + m_fixits_cannot_be_auto_applied = true; + } + + bool fixits_can_be_auto_applied_p () const + { + return !m_fixits_cannot_be_auto_applied; + } + private: bool reject_impossible_fixit (source_location where); void stop_supporting_fixits (); @@ -1686,6 +1707,7 @@ protected: semi_embedded_vec m_fixit_hints; bool m_seen_impossible_fixit; + bool m_fixits_cannot_be_auto_applied; }; /* A fix-it hint: a suggested insertion, replacement, or deletion of text. diff --git a/libcpp/line-map.c b/libcpp/line-map.c index c4b7cb23651..5caaf6b2d68 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -2012,7 +2012,8 @@ rich_location::rich_location (line_maps *set, source_location loc) : m_column_override (0), m_have_expanded_location (false), m_fixit_hints (), - m_seen_impossible_fixit (false) + m_seen_impossible_fixit (false), + m_fixits_cannot_be_auto_applied (false) { add_range (loc, true); } -- 2.30.2