aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2016-08-31 00:35:01 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2016-08-31 00:35:01 +0000
commitb816477a5ad7277b3a588e9a58cbcd764152b8d2 (patch)
tree4e3390b81b9f7a7b900db1de9278ee74805abf77 /gcc
parentfb8e9c5e8ee12831db4a020f7ccb63ac7bbf9dee (diff)
downloadgcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.zip
gcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.tar.gz
gcc-b816477a5ad7277b3a588e9a58cbcd764152b8d2.tar.bz2
Remove arbitrary limits from rich_location
This patch eliminates the hard-coded limits within rich_location (up to 3 ranges, up to 2 fixits). The common case is still handled by embedding the values inside rich_location - it only uses dynamic allocation if these limits are exceeded, so creation of rich_location instances on the stack should still be fast. This is implemented via a new container class, semi_embedded_vec <T, N>. gcc/ChangeLog: * diagnostic-show-locus.c (colorizer::begin_state): Support more than 3 ranges per diagnostic by alternating between color 1 and color 2. (layout::layout): Replace use of rich_location::MAX_RANGES with richloc->get_num_locations (). (layout::calculate_line_spans): Replace use of rich_location::MAX_RANGES with m_layout_ranges.length (). (layout::print_annotation_line): Handle arbitrary numbers of ranges in caret-printing by defaulting to '^'. (selftest::test_one_liner_many_fixits): New function. (test_diagnostic_show_locus_one_liner): Call it. * diagnostic.c (diagnostic_initialize): Update for renaming of rich_location::MAX_RANGES to rich_location::STATICALLY_ALLOCATED_RANGES. * diagnostic.h (struct diagnostic_context): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-show-locus-bw.c (test_many_nested_locations): New function. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (test_show_locus): Handle "test_many_nested_locations". libcpp/ChangeLog: * include/line-map.h (class semi_embedded_vec): New class. (semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec): New ctor. (semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec): New dtor. (semi_embedded_vec<T, NUM_EMBEDDED>::operator[]): New methods. (semi_embedded_vec<T, NUM_EMBEDDED>::push): New method. (semi_embedded_vec<T, NUM_EMBEDDED>::truncate): New method. (rich_location::get_num_locations): Reimplement in terms of m_ranges. (rich_location::get_range): Make non-inline. (rich_location::get_num_fixit_hints): Reimplement in terms of m_fixit_hints. (rich_location::add_fixit): New function. (rich_location::MAX_RANGES): Rename to... (rich_location::STATICALLY_ALLOCATED_RANGES): ...this. (rich_location::MAX_FIXIT_HINTS): Rename to... (rich_location::STATICALLY_ALLOCATED_RANGES): ...this, and make private. (rich_location::m_num_ranges): Eliminate in favor of... (rich_location::m_ranges): ...this, converting from a fixed-size array to a semi_embedded_vec. (rich_location::m_num_fixit_hints): Eliminate in favor of... (rich_location::m_fixit_hints): ...this, converting from a fixed-size array to a semi_embedded_vec. * line-map.c (rich_location::rich_location): Update for above changes. (rich_location::~rich_location): Likewise. (rich_location::get_loc): Likewise. (rich_location::get_range): New methods. (rich_location::add_range): Update for above changes. (rich_location::set_range): Likewise. (rich_location::add_fixit_insert): Likewise. (rich_location::add_fixit_replace): Likewise. (rich_location::get_last_fixit_hint): Likewise. (rich_location::reject_impossible_fixit): Likewise. (rich_location::add_fixit): New method. From-SVN: r239879
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/diagnostic-show-locus.c64
-rw-r--r--gcc/diagnostic.c2
-rw-r--r--gcc/diagnostic.h2
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c44
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c53
7 files changed, 181 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa764e8..54f2f7a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,23 @@
2016-08-30 David Malcolm <dmalcolm@redhat.com>
+ * diagnostic-show-locus.c (colorizer::begin_state): Support more
+ than 3 ranges per diagnostic by alternating between color 1 and
+ color 2.
+ (layout::layout): Replace use of rich_location::MAX_RANGES
+ with richloc->get_num_locations ().
+ (layout::calculate_line_spans): Replace use of
+ rich_location::MAX_RANGES with m_layout_ranges.length ().
+ (layout::print_annotation_line): Handle arbitrary numbers of
+ ranges in caret-printing by defaulting to '^'.
+ (selftest::test_one_liner_many_fixits): New function.
+ (test_diagnostic_show_locus_one_liner): Call it.
+ * diagnostic.c (diagnostic_initialize): Update for renaming
+ of rich_location::MAX_RANGES to
+ rich_location::STATICALLY_ALLOCATED_RANGES.
+ * diagnostic.h (struct diagnostic_context): Likewise.
+
+2016-08-30 David Malcolm <dmalcolm@redhat.com>
+
* selftest.c (selftest::named_temp_file::named_temp_file): New
ctor.
(selftest::temp_source_file::~temp_source_file): Move to...
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 60f6820..a22a660 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -317,8 +317,12 @@ colorizer::begin_state (int state)
break;
default:
- /* We don't expect more than 3 ranges per diagnostic. */
- gcc_unreachable ();
+ /* For ranges beyond 2, alternate between color 1 and color 2. */
+ {
+ gcc_assert (state > 2);
+ pp_string (m_context->printer,
+ state % 2 ? m_range1 : m_range2);
+ }
break;
}
}
@@ -720,8 +724,8 @@ layout::layout (diagnostic_context * context,
m_exploc (richloc->get_expanded_location (0)),
m_colorizer (context, diagnostic_kind),
m_colorize_source_p (context->colorize_source_p),
- m_layout_ranges (rich_location::MAX_RANGES),
- m_line_spans (1 + rich_location::MAX_RANGES),
+ m_layout_ranges (richloc->get_num_locations ()),
+ m_line_spans (1 + richloc->get_num_locations ()),
m_x_offset (0)
{
source_location primary_loc = richloc->get_range (0)->m_loc;
@@ -904,7 +908,7 @@ layout::calculate_line_spans ()
/* Populate tmp_spans with individual spans, for each of
m_exploc, and for m_layout_ranges. */
- auto_vec<line_span> tmp_spans (1 + rich_location::MAX_RANGES);
+ auto_vec<line_span> tmp_spans (1 + m_layout_ranges.length ());
tmp_spans.safe_push (line_span (m_exploc.line, m_exploc.line));
for (unsigned int i = 0; i < m_layout_ranges.length (); i++)
{
@@ -1050,8 +1054,15 @@ layout::print_annotation_line (int row, const line_bounds lbounds)
/* Within a range. Draw either the caret or an underline. */
m_colorizer.set_range (state.range_idx);
if (state.draw_caret_p)
- /* Draw the caret. */
- pp_character (m_pp, m_context->caret_chars[state.range_idx]);
+ {
+ /* Draw the caret. */
+ char caret_char;
+ if (state.range_idx < rich_location::STATICALLY_ALLOCATED_RANGES)
+ caret_char = m_context->caret_chars[state.range_idx];
+ else
+ caret_char = '^';
+ pp_character (m_pp, caret_char);
+ }
else
pp_character (m_pp, '~');
}
@@ -1654,6 +1665,44 @@ test_one_liner_fixit_validation_adhoc_locations ()
}
}
+/* Ensure that we can add an arbitrary number of fix-it hints to a
+ rich_location. */
+
+static void
+test_one_liner_many_fixits ()
+{
+ test_diagnostic_context dc;
+ location_t equals = linemap_position_for_column (line_table, 5);
+ rich_location richloc (line_table, equals);
+ for (int i = 0; i < 19; i++)
+ richloc.add_fixit_insert ("a");
+ ASSERT_EQ (19, richloc.get_num_fixit_hints ());
+ diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+ ASSERT_STREQ ("\n"
+ " foo = bar.field;\n"
+ " ^\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n"
+ " a\n",
+ pp_formatted_text (dc.printer));
+}
+
/* Run the various one-liner tests. */
static void
@@ -1687,6 +1736,7 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_)
test_one_liner_fixit_replace_non_equal_range ();
test_one_liner_fixit_replace_equal_secondary_range ();
test_one_liner_fixit_validation_adhoc_locations ();
+ test_one_liner_many_fixits ();
}
/* Verify that fix-it hints are appropriately consolidated.
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index b47da38..47b4c79 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -147,7 +147,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
context->classify_diagnostic[i] = DK_UNSPECIFIED;
context->show_caret = false;
diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
- for (i = 0; i < rich_location::MAX_RANGES; i++)
+ for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
context->caret_chars[i] = '^';
context->show_option_requested = false;
context->abort_on_error = false;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 104e39c..0727644 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -109,7 +109,7 @@ struct diagnostic_context
int caret_max_width;
/* Character used for caret diagnostics. */
- char caret_chars[rich_location::MAX_RANGES];
+ char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
/* True if we should print the command line option which controls
each diagnostic, if known. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6e3b706..cf97b39 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2016-08-30 David Malcolm <dmalcolm@redhat.com>
+ * gcc.dg/plugin/diagnostic-test-show-locus-bw.c
+ (test_many_nested_locations): New function.
+ * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+ (test_show_locus): Handle "test_many_nested_locations".
+
+2016-08-30 David Malcolm <dmalcolm@redhat.com>
+
* g++.dg/template/double-greater-than-fixit.C: New test case.
2016-08-30 Eric Botcazou <ebotcazou@adacore.com>
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 2748fa1..e8112bf 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
@@ -205,3 +205,47 @@ int test_percent_q_plus_d (void)
{ dg-end-multiline-output "" } */
return local;
}
+
+/* Test of many nested locations and fixits. */
+
+void test_many_nested_locations (void)
+{
+ /* { dg-warning "test of 70 locations" }
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+ sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
+ aute irure dolor in reprehenderit in voluptate velit esse cillum
+ dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ cupidatat non proident, sunt in culpa qui officia deserunt
+ mollit anim id est laborum.
+ */
+/* { dg-begin-multiline-output "" }
+ /*
+ ^
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+ ^~~~~ ^~~~~ ^~~~~ ^~~ ^~~~ ^~~~~~~~~~~ ^~~~~~~~~~ ^~~~
+ LOREM IPSUM DOLOR SIT AMET CONSECTETUR ADIPISCING ELIT
+ sed do eiusmod tempor incididunt ut labore et dolore magna
+ ^~~ ^~ ^~~~~~~ ^~~~~~ ^~~~~~~~~~ ^~ ^~~~~~ ^~ ^~~~~~ ^~~~~
+ SED DO EIUSMOD TEMPOR INCIDIDUNT UT LABORE ET DOLORE MAGNA
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ^~~~~~ ^~ ^~~~ ^~ ^~~~~ ^~~~~~ ^~~~ ^~~~~~~ ^~~~~~~~~~~~
+ ALIQUA UT ENIM AD MINIM VENIAM QUIS NOSTRUD EXERCITATION
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
+ ^~~~~~~ ^~~~~~~ ^~~~ ^~ ^~~~~~~ ^~ ^~ ^~~~~~~ ^~~~~~~~~ ^~~~
+ ULLAMCO LABORIS NISI UT ALIQUIP EX EA COMMODO CONSEQUAT DUIS
+ aute irure dolor in reprehenderit in voluptate velit esse cillum
+ ^~~~ ^~~~~ ^~~~~ ^~ ^~~~~~~~~~~~~ ^~ ^~~~~~~~~ ^~~~~ ^~~~ ^~~~~~
+ AUTE IRURE DOLOR IN REPREHENDERIT IN VOLUPTATE VELIT ESSE CILLUM
+ dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ ^~~~~~ ^~ ^~~~~~ ^~~~~ ^~~~~~~~ ^~~~~~~~~ ^~~~ ^~~~~~~~
+ DOLORE EU FUGIAT NULLA PARIATUR EXCEPTEUR SINT OCCAECAT
+ cupidatat non proident, sunt in culpa qui officia deserunt
+ ^~~~~~~~~ ^~~ ^~~~~~~~ ^~~~ ^~ ^~~~~ ^~~ ^~~~~~~ ^~~~~~~~
+ CUPIDATAT NON PROIDENT SUNT IN CULPA QUI OFFICIA DESERUNT
+ mollit anim id est laborum.
+ ^~~~~~ ^~~~ ^~ ^~~ ^~~~~~~
+ MOLLIT ANIM ID EST LABORUM
+ { dg-end-multiline-output "" } */
+}
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 d57400d..ea28f04 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
@@ -325,6 +325,59 @@ test_show_locus (function *fun)
warning_at (input_location, 0,
"example of plus in format code for %q+D", local);
}
+
+ /* Example of many locations and many fixits.
+ Underline (separately) every word in a comment, and convert them
+ to upper case. */
+ if (0 == strcmp (fnname, "test_many_nested_locations"))
+ {
+ const char *file = LOCATION_FILE (fnstart);
+ const int start_line = fnstart_line + 2;
+ const int finish_line = start_line + 7;
+ location_t loc = get_loc (start_line - 1, 2);
+ rich_location richloc (line_table, loc);
+ for (int line = start_line; line <= finish_line; line++)
+ {
+ int line_size;
+ const char *content = location_get_source_line (file, line,
+ &line_size);
+ gcc_assert (content);
+ /* Split line up into words. */
+ for (int idx = 0; idx < line_size; idx++)
+ {
+ if (ISALPHA (content[idx]))
+ {
+ int start_idx = idx;
+ while (idx < line_size && ISALPHA (content[idx]))
+ idx++;
+ if (idx == line_size || !ISALPHA (content[idx]))
+ {
+ location_t start_of_word = get_loc (line, start_idx);
+ location_t end_of_word = get_loc (line, idx - 1);
+ location_t word
+ = make_location (start_of_word, start_of_word,
+ end_of_word);
+ richloc.add_range (word, true);
+
+ /* Add a fixit, converting to upper case. */
+ char *copy = xstrndup (content + start_idx,
+ idx - start_idx);
+ for (char *ch = copy; *ch; ch++)
+ *ch = TOUPPER (*ch);
+ richloc.add_fixit_replace (word, copy);
+ free (copy);
+ }
+ }
+ }
+ }
+ /* Verify that we added enough locations to fully exercise
+ rich_location. We want to exceed both the
+ statically-allocated buffer in class rich_location,
+ and then trigger a reallocation of the dynamic buffer. */
+ gcc_assert (richloc.get_num_locations () > 3 + (2 * 16));
+ warning_at_rich_loc (&richloc, 0, "test of %i locations",
+ richloc.get_num_locations ());
+ }
}
unsigned int