aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2016-08-29 20:42:57 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2016-08-29 20:42:57 +0000
commit2aa514130a99ffeaff6ae3cdddf609be358022be (patch)
tree6d574e6eb977268815029f2ec08618e51a518b9a
parentadfa1e6b37f5b18570a6200a0784bd8074c5f1e0 (diff)
downloadgcc-2aa514130a99ffeaff6ae3cdddf609be358022be.zip
gcc-2aa514130a99ffeaff6ae3cdddf609be358022be.tar.gz
gcc-2aa514130a99ffeaff6ae3cdddf609be358022be.tar.bz2
Allow the use of ad-hoc locations for fix-it hints
Currently the fix-it validator rejects ad-hoc locations. Fix this by calling get_pure_location on the input locations to add_fixit_insert/replace. Doing so requires moving get_pure_location from gcc to libcpp. gcc/ChangeLog: * diagnostic-show-locus.c (selftest::test_one_liner_fixit_validation_adhoc_locations): New function. (selftest::test_diagnostic_show_locus_one_liner): Call it. * input.c (get_pure_location): Move to libcpp/line-map.c. * input.h (get_pure_location): Convert decl to an inline function calling implementation in libcpp. libcpp/ChangeLog: * include/line-map.h (get_pure_location): New decl. * line-map.c (get_pure_location): Move here, from gcc/input.c, adding a line_maps * param. (rich_location::add_fixit_insert): Call get_pure_location on "where". (rich_location::add_fixit_replace): Call get_pure_location on the end-points. From-SVN: r239843
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/diagnostic-show-locus.c70
-rw-r--r--gcc/input.c22
-rw-r--r--gcc/input.h6
-rw-r--r--libcpp/ChangeLog9
-rw-r--r--libcpp/include/line-map.h6
-rw-r--r--libcpp/line-map.c27
7 files changed, 127 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 065b9a3..4783518 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2016-08-29 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-show-locus.c
+ (selftest::test_one_liner_fixit_validation_adhoc_locations): New
+ function.
+ (selftest::test_diagnostic_show_locus_one_liner): Call it.
+ * input.c (get_pure_location): Move to libcpp/line-map.c.
+ * input.h (get_pure_location): Convert decl to an inline function
+ calling implementation in libcpp.
+
2016-08-29 Uros Bizjak <ubizjak@gmail.com>
PR target/77403
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index f3f661e..ba52f24 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -1594,6 +1594,75 @@ test_one_liner_fixit_replace_equal_secondary_range ()
pp_formatted_text (dc.printer));
}
+/* Verify that we can use ad-hoc locations when adding fixits to a
+ rich_location. */
+
+static void
+test_one_liner_fixit_validation_adhoc_locations ()
+{
+ /* Generate a range that's too long to be packed, so must
+ be stored as an ad-hoc location (given the defaults
+ of 5 bits or 0 bits of packed range); 41 columns > 2**5. */
+ const location_t c7 = linemap_position_for_column (line_table, 7);
+ const location_t c47 = linemap_position_for_column (line_table, 47);
+ const location_t loc = make_location (c7, c7, c47);
+
+ if (c47 > LINE_MAP_MAX_LOCATION_WITH_COLS)
+ return;
+
+ ASSERT_TRUE (IS_ADHOC_LOC (loc));
+
+ /* Insert. */
+ {
+ rich_location richloc (line_table, loc);
+ richloc.add_fixit_insert (loc, "test");
+ /* It should not have been discarded by the validator. */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+
+ test_diagnostic_context dc;
+ diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+ ASSERT_STREQ ("\n"
+ " foo = bar.field;\n"
+ " ^~~~~~~~~~ \n"
+ " test\n",
+ pp_formatted_text (dc.printer));
+ }
+
+ /* Remove. */
+ {
+ rich_location richloc (line_table, loc);
+ source_range range = source_range::from_locations (loc, c47);
+ richloc.add_fixit_remove (range);
+ /* It should not have been discarded by the validator. */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+
+ test_diagnostic_context dc;
+ diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+ ASSERT_STREQ ("\n"
+ " foo = bar.field;\n"
+ " ^~~~~~~~~~ \n"
+ " -----------------------------------------\n",
+ pp_formatted_text (dc.printer));
+ }
+
+ /* Replace. */
+ {
+ rich_location richloc (line_table, loc);
+ source_range range = source_range::from_locations (loc, c47);
+ richloc.add_fixit_replace (range, "test");
+ /* It should not have been discarded by the validator. */
+ ASSERT_EQ (1, richloc.get_num_fixit_hints ());
+
+ test_diagnostic_context dc;
+ diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+ ASSERT_STREQ ("\n"
+ " foo = bar.field;\n"
+ " ^~~~~~~~~~ \n"
+ " test\n",
+ pp_formatted_text (dc.printer));
+ }
+}
+
/* Run the various one-liner tests. */
static void
@@ -1626,6 +1695,7 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_)
test_one_liner_fixit_replace ();
test_one_liner_fixit_replace_non_equal_range ();
test_one_liner_fixit_replace_equal_secondary_range ();
+ test_one_liner_fixit_validation_adhoc_locations ();
}
/* Verify that fix-it hints are appropriately consolidated.
diff --git a/gcc/input.c b/gcc/input.c
index 4ec218d..a3fe542 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -838,28 +838,6 @@ expansion_point_location (source_location location)
LRK_MACRO_EXPANSION_POINT, NULL);
}
-/* Given location LOC, strip away any packed range information
- or ad-hoc information. */
-
-location_t
-get_pure_location (location_t loc)
-{
- if (IS_ADHOC_LOC (loc))
- loc
- = line_table->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
-
- if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
- return loc;
-
- if (loc < RESERVED_LOCATION_COUNT)
- return loc;
-
- const line_map *map = linemap_lookup (line_table, loc);
- const line_map_ordinary *ordmap = linemap_check_ordinary (map);
-
- return loc & ~((1 << ordmap->m_range_bits) - 1);
-}
-
/* Construct a location with caret at CARET, ranging from START to
finish e.g.
diff --git a/gcc/input.h b/gcc/input.h
index ecf8db3..fd21f34 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -77,7 +77,11 @@ extern location_t input_location;
#define from_macro_expansion_at(LOC) \
((linemap_location_from_macro_expansion_p (line_table, LOC)))
-extern location_t get_pure_location (location_t loc);
+static inline location_t
+get_pure_location (location_t loc)
+{
+ return get_pure_location (line_table, loc);
+}
/* Get the start of any range encoded within location LOC. */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 56971ad..37825f5 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,5 +1,14 @@
2016-08-26 David Malcolm <dmalcolm@redhat.com>
+ * include/line-map.h (get_pure_location): New decl.
+ * line-map.c (get_pure_location): Move here, from gcc/input.c, adding
+ a line_maps * param.
+ (rich_location::add_fixit_insert): Call get_pure_location on "where".
+ (rich_location::add_fixit_replace): Call get_pure_location on the
+ end-points.
+
+2016-08-26 David Malcolm <dmalcolm@redhat.com>
+
* include/line-map.h (rich_location): Eliminate unimplemented
constructor based on source_range.
(rich_location::get_last_fixit_hint): New method.
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 0fc4848..d9c31de 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -1002,6 +1002,12 @@ IS_ADHOC_LOC (source_location loc)
bool
pure_location_p (line_maps *set, source_location loc);
+/* Given location LOC within SET, strip away any packed range information
+ or ad-hoc information. */
+
+extern source_location get_pure_location (line_maps *set,
+ source_location loc);
+
/* Combine LOC and BLOCK, giving a combined adhoc location. */
inline source_location
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 8fe48bd..f5b1586 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -311,6 +311,28 @@ pure_location_p (line_maps *set, source_location loc)
return true;
}
+/* Given location LOC within SET, strip away any packed range information
+ or ad-hoc information. */
+
+source_location
+get_pure_location (line_maps *set, source_location loc)
+{
+ if (IS_ADHOC_LOC (loc))
+ loc
+ = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
+ if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
+ return loc;
+
+ if (loc < RESERVED_LOCATION_COUNT)
+ return loc;
+
+ const line_map *map = linemap_lookup (set, loc);
+ const line_map_ordinary *ordmap = linemap_check_ordinary (map);
+
+ return loc & ~((1 << ordmap->m_range_bits) - 1);
+}
+
/* Finalize the location_adhoc_data structure. */
void
location_adhoc_data_fini (struct line_maps *set)
@@ -2077,6 +2099,8 @@ void
rich_location::add_fixit_insert (source_location where,
const char *new_content)
{
+ where = get_pure_location (m_line_table, where);
+
if (reject_impossible_fixit (where))
return;
@@ -2141,6 +2165,9 @@ rich_location::add_fixit_replace (source_range src_range,
{
linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
+ src_range.m_start = get_pure_location (m_line_table, src_range.m_start);
+ src_range.m_finish = get_pure_location (m_line_table, src_range.m_finish);
+
if (reject_impossible_fixit (src_range.m_start))
return;
if (reject_impossible_fixit (src_range.m_finish))