aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/diagnostic-show-locus.c155
-rw-r--r--gcc/gcc-rich-location.h5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-fields-2.c23
5 files changed, 191 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e719a87..cfa9c3d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2016-08-26 David Malcolm <dmalcolm@redhat.com>
+ * 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.
+
+2016-08-26 David Malcolm <dmalcolm@redhat.com>
+
* diagnostic-color.c (color_dict): Add "fixit-insert" and
"fixit-delete".
(parse_gcc_colors): Update description of default GCC_COLORS.
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 94b7349..f3f661e 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -1628,6 +1628,160 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_)
test_one_liner_fixit_replace_equal_secondary_range ();
}
+/* Verify that fix-it hints are appropriately consolidated.
+
+ If any fix-it hints in a rich_location involve locations beyond
+ LINE_MAP_MAX_LOCATION_WITH_COLS, then we can't reliably apply
+ the fix-it as a whole, so there should be none.
+
+ Otherwise, verify that consecutive "replace" and "remove" fix-its
+ are merged, and that other fix-its remain separate. */
+
+static void
+test_fixit_consolidation (const line_table_case &case_)
+{
+ line_table_test ltt (case_);
+
+ linemap_add (line_table, LC_ENTER, false, "test.c", 1);
+
+ const location_t c10 = linemap_position_for_column (line_table, 10);
+ const location_t c15 = linemap_position_for_column (line_table, 15);
+ const location_t c16 = linemap_position_for_column (line_table, 16);
+ const location_t c17 = linemap_position_for_column (line_table, 17);
+ const location_t c20 = linemap_position_for_column (line_table, 20);
+ const location_t caret = c10;
+
+ /* Insert + insert. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_insert (c10, "foo");
+ richloc.add_fixit_insert (c15, "bar");
+
+ if (c15 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ /* They should not have been merged. */
+ ASSERT_EQ (2, richloc.get_num_fixit_hints ());
+ }
+
+ /* Insert + replace. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_insert (c10, "foo");
+ richloc.add_fixit_replace (source_range::from_locations (c15, c17),
+ "bar");
+
+ if (c17 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ /* They should not have been merged. */
+ ASSERT_EQ (2, richloc.get_num_fixit_hints ());
+ }
+
+ /* Replace + non-consecutive insert. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_replace (source_range::from_locations (c10, c15),
+ "bar");
+ richloc.add_fixit_insert (c17, "foo");
+
+ if (c17 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ /* They should not have been merged. */
+ ASSERT_EQ (2, richloc.get_num_fixit_hints ());
+ }
+
+ /* Replace + non-consecutive replace. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_replace (source_range::from_locations (c10, c15),
+ "foo");
+ richloc.add_fixit_replace (source_range::from_locations (c17, c20),
+ "bar");
+
+ if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ /* They should not have been merged. */
+ ASSERT_EQ (2, richloc.get_num_fixit_hints ());
+ }
+
+ /* Replace + consecutive replace. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_replace (source_range::from_locations (c10, c15),
+ "foo");
+ richloc.add_fixit_replace (source_range::from_locations (c16, c20),
+ "bar");
+
+ if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ {
+ /* They should have been merged into a single "replace". */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+ const fixit_hint *hint = richloc.get_fixit_hint (0);
+ ASSERT_EQ (fixit_hint::REPLACE, hint->get_kind ());
+ const fixit_replace *replace = (const fixit_replace *)hint;
+ ASSERT_STREQ ("foobar", replace->get_string ());
+ ASSERT_EQ (c10, replace->get_range ().m_start);
+ ASSERT_EQ (c20, replace->get_range ().m_finish);
+ }
+ }
+
+ /* Replace + consecutive removal. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_replace (source_range::from_locations (c10, c15),
+ "foo");
+ richloc.add_fixit_remove (source_range::from_locations (c16, c20));
+
+ if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ {
+ /* They should have been merged into a single replace, with the
+ range extended to cover that of the removal. */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+ const fixit_hint *hint = richloc.get_fixit_hint (0);
+ ASSERT_EQ (fixit_hint::REPLACE, hint->get_kind ());
+ const fixit_replace *replace = (const fixit_replace *)hint;
+ ASSERT_STREQ ("foo", replace->get_string ());
+ ASSERT_EQ (c10, replace->get_range ().m_start);
+ ASSERT_EQ (c20, replace->get_range ().m_finish);
+ }
+ }
+
+ /* Consecutive removals. */
+ {
+ rich_location richloc (line_table, caret);
+ richloc.add_fixit_remove (source_range::from_locations (c10, c15));
+ richloc.add_fixit_remove (source_range::from_locations (c16, c20));
+
+ if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ /* Bogus column info for 2nd fixit, so no fixits. */
+ ASSERT_EQ (0, richloc.get_num_fixit_hints ());
+ else
+ {
+ /* They should have been merged into a single "replace-with-empty". */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+ const fixit_hint *hint = richloc.get_fixit_hint (0);
+ ASSERT_EQ (fixit_hint::REPLACE, hint->get_kind ());
+ const fixit_replace *replace = (const fixit_replace *)hint;
+ ASSERT_STREQ ("", replace->get_string ());
+ ASSERT_EQ (c10, replace->get_range ().m_start);
+ ASSERT_EQ (c20, replace->get_range ().m_finish);
+ }
+ }
+}
+
/* Run all of the selftests within this file. */
void
@@ -1642,6 +1796,7 @@ diagnostic_show_locus_c_tests ()
test_diagnostic_show_locus_unknown_location ();
for_each_line_table_case (test_diagnostic_show_locus_one_liner);
+ for_each_line_table_case (test_fixit_consolidation);
}
} // namespace selftest
diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h
index aa69b2e..cc5987f 100644
--- a/gcc/gcc-rich-location.h
+++ b/gcc/gcc-rich-location.h
@@ -31,11 +31,6 @@ class gcc_rich_location : public rich_location
gcc_rich_location (source_location loc) :
rich_location (line_table, loc) {}
- /* Constructing from a source_range. */
- gcc_rich_location (source_range src_range) :
- rich_location (src_range) {}
-
-
/* Methods for adding ranges via gcc entities. */
void
add_expr (tree expr);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 352769a..952380f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2016-08-26 David Malcolm <dmalcolm@redhat.com>
+ * gcc.dg/spellcheck-fields-2.c (test): Move
+ dg-begin/end-multiline-output within function body.
+ (test_macro): New function.
+
+2016-08-26 David Malcolm <dmalcolm@redhat.com>
+
* gcc.dg/plugin/diagnostic-test-show-locus-color.c
(test_fixit_insert): Update expected output.
(test_fixit_remove): Likewise.
diff --git a/gcc/testsuite/gcc.dg/spellcheck-fields-2.c b/gcc/testsuite/gcc.dg/spellcheck-fields-2.c
index d6ebff1..7c54214 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-fields-2.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-fields-2.c
@@ -9,7 +9,6 @@ union u
int test (union u *ptr)
{
return ptr->colour; /* { dg-error "did you mean .color.?" } */
-}
/* Verify that we get an underline and a fixit hint. */
/* { dg-begin-multiline-output "" }
@@ -17,3 +16,25 @@ int test (union u *ptr)
^~~~~~
color
{ dg-end-multiline-output "" } */
+}
+
+
+/* Verify that we don't offer a fixit hint in the presence of
+ a macro. */
+int test_macro (union u *ptr)
+{
+#define FIELD colour /* { dg-error "did you mean .color.?" } */
+ return ptr->FIELD;
+
+/* { dg-begin-multiline-output "" }
+ #define FIELD colour
+ ^
+ { dg-end-multiline-output "" } */
+
+/* { dg-begin-multiline-output "" }
+ return ptr->FIELD;
+ ^~~~~
+ { dg-end-multiline-output "" } */
+
+#undef FIELD
+}