aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2017-06-20 10:40:38 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2017-06-20 10:40:38 +0000
commitc7a980b80b3a46ad24940269f6b85a75cdb94a60 (patch)
treefe86d10819506cdb8f17e6172d8ed766eb12c2fa /gcc
parentad2f2a35d33ea79f95b70f8d96ee1445fabed402 (diff)
downloadgcc-c7a980b80b3a46ad24940269f6b85a75cdb94a60.zip
gcc-c7a980b80b3a46ad24940269f6b85a75cdb94a60.tar.gz
gcc-c7a980b80b3a46ad24940269f6b85a75cdb94a60.tar.bz2
Prevent fix-it hints from affecting more than one line
Attempts to apply a removal or replacement fix-it hint to a source range that covers multiple lines currently lead to nonsensical results from the printing code in diagnostic-show-locus.c. We were already filtering them out in edit-context.c (leading to -fdiagnostics-generate-patch not generating any output for the whole TU). Reject attempts to add such fix-it hints within rich_location, fixing the diagnostic-show-locus.c issue. gcc/ChangeLog: * diagnostic-show-locus.c (selftest::test_fixit_deletion_affecting_newline): New function. (selftest::diagnostic_show_locus_c_tests): Call it. libcpp/ChangeLog: * include/line-map.h (class rich_location): Document that attempts to delete or replace a range *affecting* multiple lines will fail. * line-map.c (rich_location::maybe_add_fixit): Implement this restriction. From-SVN: r249403
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/diagnostic-show-locus.c48
2 files changed, 54 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7cb99a6..4293a05 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-20 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-show-locus.c
+ (selftest::test_fixit_deletion_affecting_newline): New function.
+ (selftest::diagnostic_show_locus_c_tests): Call it.
+
2017-06-20 Andreas Schwab <schwab@suse.de>
PR target/80970
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index f410a32..8bf4d9e 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -2793,6 +2793,53 @@ test_fixit_replace_containing_newline (const line_table_case &case_)
pp_formatted_text (dc.printer));
}
+/* Fix-it hint, attempting to delete a newline.
+ This will fail, as we currently only support fix-it hints that
+ affect one line at a time. */
+
+static void
+test_fixit_deletion_affecting_newline (const line_table_case &case_)
+{
+ /* Create a tempfile and write some text to it.
+ ..........................0000000001111.
+ ..........................1234567890123. */
+ const char *old_content = ("foo = bar (\n"
+ " );\n");
+
+ temp_source_file tmp (SELFTEST_LOCATION, ".c", old_content);
+ line_table_test ltt (case_);
+ const line_map_ordinary *ord_map = linemap_check_ordinary
+ (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
+ linemap_line_start (line_table, 1, 100);
+
+ /* Attempt to delete the " (\n...)". */
+ location_t start
+ = linemap_position_for_line_and_column (line_table, ord_map, 1, 10);
+ location_t caret
+ = linemap_position_for_line_and_column (line_table, ord_map, 1, 11);
+ location_t finish
+ = linemap_position_for_line_and_column (line_table, ord_map, 2, 7);
+ location_t loc = make_location (caret, start, finish);
+ rich_location richloc (line_table, loc);
+ richloc. add_fixit_remove ();
+
+ /* Fix-it hints that affect more than one line are not yet supported, so
+ the fix-it should not be displayed. */
+ ASSERT_TRUE (richloc.seen_impossible_fixit_p ());
+
+ if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ return;
+
+ test_diagnostic_context dc;
+ diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+ ASSERT_STREQ ("\n"
+ " foo = bar (\n"
+ " ~^\n"
+ " );\n"
+ " ~ \n",
+ pp_formatted_text (dc.printer));
+}
+
/* Run all of the selftests within this file. */
void
@@ -2813,6 +2860,7 @@ diagnostic_show_locus_c_tests ()
for_each_line_table_case (test_fixit_insert_containing_newline);
for_each_line_table_case (test_fixit_insert_containing_newline_2);
for_each_line_table_case (test_fixit_replace_containing_newline);
+ for_each_line_table_case (test_fixit_deletion_affecting_newline);
}
} // namespace selftest