diff options
Diffstat (limited to 'gcc/diagnostic.cc')
-rw-r--r-- | gcc/diagnostic.cc | 247 |
1 files changed, 154 insertions, 93 deletions
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 82d7f94..7e5ac87 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -49,7 +49,6 @@ along with GCC; see the file COPYING3. If not see #include "pretty-print-urlifier.h" #include "logical-location.h" #include "diagnostic-buffer.h" -#include "make-unique.h" #ifdef HAVE_TERMIOS_H # include <termios.h> @@ -96,7 +95,7 @@ int get_terminal_width (void) { const char * s = getenv ("COLUMNS"); - if (s != NULL) { + if (s != nullptr) { int n = atoi (s); if (n > 0) return n; @@ -223,7 +222,7 @@ diagnostic_context::initialize (int n_opts) { /* Allocate a basic pretty-printer. Clients will replace this a much more elaborated pretty-printer if they wish. */ - m_reference_printer = ::make_unique<pretty_printer> ().release (); + m_reference_printer = std::make_unique<pretty_printer> ().release (); m_file_cache = new file_cache (); m_diagnostic_counters.clear (); @@ -251,7 +250,10 @@ diagnostic_context::initialize (int n_opts) m_internal_error = nullptr; m_adjust_diagnostic_info = nullptr; m_text_callbacks.m_begin_diagnostic = default_diagnostic_text_starter; - m_text_callbacks.m_start_span = default_diagnostic_start_span_fn; + m_text_callbacks.m_text_start_span + = default_diagnostic_start_span_fn<to_text>; + m_text_callbacks.m_html_start_span + = default_diagnostic_start_span_fn<to_html>; m_text_callbacks.m_end_diagnostic = default_diagnostic_text_finalizer; m_option_mgr = nullptr; m_urlifier_stack = new auto_vec<urlifier_stack_node> (); @@ -283,6 +285,7 @@ diagnostic_context::initialize (int n_opts) m_diagnostic_groups.m_group_nesting_depth = 0; m_diagnostic_groups.m_diagnostic_nesting_level = 0; m_diagnostic_groups.m_emission_count = 0; + m_diagnostic_groups.m_inhibiting_notes_from = 0; m_output_sinks.safe_push (new diagnostic_text_output_format (*this, nullptr, true)); m_set_locations_cb = nullptr; @@ -522,6 +525,13 @@ diagnostic_context::supports_fnotice_on_stderr_p () const } void +diagnostic_context::set_main_input_filename (const char *filename) +{ + for (auto sink : m_output_sinks) + sink->set_main_input_filename (filename); +} + +void diagnostic_context:: set_client_data_hooks (std::unique_ptr<diagnostic_client_data_hooks> hooks) { @@ -580,6 +590,14 @@ diagnostic_context::pop_urlifier () delete node.m_urlifier; } +const logical_location_manager * +diagnostic_context::get_logical_location_manager () const +{ + if (!m_client_data_hooks) + return nullptr; + return m_client_data_hooks->get_logical_location_manager (); +} + const urlifier * diagnostic_context::get_urlifier () const { @@ -661,7 +679,7 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, diagnostic->message.m_format_spec = msg; diagnostic->message.m_richloc = richloc; diagnostic->richloc = richloc; - diagnostic->metadata = NULL; + diagnostic->metadata = nullptr; diagnostic->kind = kind; diagnostic->option_id = 0; } @@ -681,11 +699,11 @@ static const char *const diagnostic_kind_color[] = { #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C), #include "diagnostic.def" #undef DEFINE_DIAGNOSTIC_KIND - NULL + nullptr }; /* Get a color name for diagnostics of type KIND - Result could be NULL. */ + Result could be nullptr. */ const char * diagnostic_get_color_for_kind (diagnostic_t kind) @@ -819,12 +837,12 @@ bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, /* If we don't have any useful information, don't print anything. */ - if (filename == NULL && function == NULL) + if (filename == nullptr && function == nullptr) return 0; /* Skip functions in diagnostic.cc. */ if (*pcount == 0 - && filename != NULL + && filename != nullptr && strcmp (lbasename (filename), "diagnostic.cc") == 0) return 0; @@ -837,13 +855,13 @@ bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, } ++*pcount; - char *alc = NULL; - if (function != NULL) + char *alc = nullptr; + if (function != nullptr) { char *str = cplus_demangle_v3 (function, (DMGL_VERBOSE | DMGL_ANSI | DMGL_GNU_V3 | DMGL_PARAMS)); - if (str != NULL) + if (str != nullptr) { alc = str; function = str; @@ -855,7 +873,7 @@ bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, if (strncmp (function, bt_stop[i], len) == 0 && (function[len] == '\0' || function[len] == '(')) { - if (alc != NULL) + if (alc != nullptr) free (alc); /* Returning a non-zero value stops the backtrace. */ return 1; @@ -865,11 +883,11 @@ bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, fprintf (stderr, "0x%lx %s\n\t%s:%d\n", (unsigned long) pc, - function == NULL ? "???" : function, - filename == NULL ? "???" : filename, + function == nullptr ? "???" : function, + filename == nullptr ? "???" : filename, lineno); - if (alc != NULL) + if (alc != nullptr) free (alc); return 0; @@ -918,6 +936,7 @@ diagnostic_context::check_max_errors (bool flush) /* Take any action which is expected to happen after the diagnostic is written out. This function does not always return. */ + void diagnostic_context::action_after_output (diagnostic_t diag_kind) { @@ -954,11 +973,11 @@ diagnostic_context::action_after_output (diagnostic_t diag_kind) finish (); } - struct backtrace_state *state = NULL; + struct backtrace_state *state = nullptr; if (diag_kind == DK_ICE) - state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); + state = backtrace_create_state (nullptr, 0, bt_err_callback, nullptr); int count = 0; - if (state != NULL) + if (state != nullptr) backtrace_full (state, 2, bt_callback, bt_err_callback, (void *) &count); @@ -992,47 +1011,76 @@ diagnostic_context::action_after_output (diagnostic_t diag_kind) } } -/* class logical_location. */ +/* State whether we should inhibit notes in the current diagnostic_group and + its future children if any. */ + +void +diagnostic_context::inhibit_notes_in_group (bool inhibit) +{ + int curr_depth = (m_diagnostic_groups.m_group_nesting_depth + + m_diagnostic_groups.m_diagnostic_nesting_level); + + if (inhibit) + { + /* If we're already inhibiting, there's nothing to do. */ + if (m_diagnostic_groups.m_inhibiting_notes_from) + return; + + /* Since we're called via warning/error/... that all have their own + diagnostic_group, we must consider that we started inhibiting in their + parent. */ + gcc_assert (m_diagnostic_groups.m_group_nesting_depth > 0); + m_diagnostic_groups.m_inhibiting_notes_from = curr_depth - 1; + } + else if (m_diagnostic_groups.m_inhibiting_notes_from) + { + /* Only cancel inhibition at the depth that set it up. */ + if (curr_depth >= m_diagnostic_groups.m_inhibiting_notes_from) + return; + + m_diagnostic_groups.m_inhibiting_notes_from = 0; + } +} + +/* Return whether notes must be inhibited in the current diagnostic_group. */ + +bool +diagnostic_context::notes_inhibited_in_group () const +{ + if (m_diagnostic_groups.m_inhibiting_notes_from + && (m_diagnostic_groups.m_group_nesting_depth + + m_diagnostic_groups.m_diagnostic_nesting_level + >= m_diagnostic_groups.m_inhibiting_notes_from)) + return true; + return false; +} + +/* class logical_location_manager. */ /* Return true iff this is a function or method. */ bool -logical_location::function_p () const +logical_location_manager::function_p (key k) const { - switch (get_kind ()) + switch (get_kind (k)) { default: gcc_unreachable (); - case LOGICAL_LOCATION_KIND_UNKNOWN: - case LOGICAL_LOCATION_KIND_MODULE: - case LOGICAL_LOCATION_KIND_NAMESPACE: - case LOGICAL_LOCATION_KIND_TYPE: - case LOGICAL_LOCATION_KIND_RETURN_TYPE: - case LOGICAL_LOCATION_KIND_PARAMETER: - case LOGICAL_LOCATION_KIND_VARIABLE: + case logical_location_kind::unknown: + case logical_location_kind::module_: + case logical_location_kind::namespace_: + case logical_location_kind::type: + case logical_location_kind::return_type: + case logical_location_kind::parameter: + case logical_location_kind::variable: return false; - case LOGICAL_LOCATION_KIND_FUNCTION: - case LOGICAL_LOCATION_KIND_MEMBER: + case logical_location_kind::function: + case logical_location_kind::member: return true; } } -void -default_diagnostic_start_span_fn (const diagnostic_location_print_policy &loc_policy, - pretty_printer *pp, - expanded_location exploc) -{ - const diagnostic_column_policy &column_policy - = loc_policy.get_column_policy (); - label_text text - = column_policy.get_location_text (exploc, - loc_policy.show_column_p (), - pp_show_color (pp)); - pp_string (pp, text.get ()); - pp_newline (pp); -} - /* Interface to specify diagnostic kind overrides. Returns the previous setting, or DK_UNSPECIFIED if the parameters are out of range. If OPTION_ID is zero, the new setting is for all the @@ -1146,7 +1194,7 @@ print_parseable_fixits (file_cache &fc, gcc_assert (richloc); char *saved_prefix = pp_take_prefix (pp); - pp_set_prefix (pp, NULL); + pp_set_prefix (pp, nullptr); for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++) { @@ -1382,7 +1430,10 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) bool was_warning = (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN); if (was_warning && m_inhibit_warnings) - return false; + { + inhibit_notes_in_group (); + return false; + } if (m_adjust_diagnostic_info) m_adjust_diagnostic_info (this, diagnostic); @@ -1398,18 +1449,6 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) if (diagnostic->kind == DK_NOTE && m_inhibit_notes_p) return false; - if (m_lock > 0) - { - /* If we're reporting an ICE in the middle of some other error, - try to flush out the previous error, then let this one - through. Don't do this more than once. */ - if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) - && m_lock == 1) - pp_newline_and_flush (m_reference_printer); - else - error_recursion (); - } - /* If the user requested that warnings be treated as errors, so be it. Note that we do this before the next block so that individual warnings can be overridden back to warnings with @@ -1424,7 +1463,10 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) not disabled by #pragma GCC diagnostic anywhere along the inlining stack. . */ if (!diagnostic_enabled (diagnostic)) - return false; + { + inhibit_notes_in_group (); + return false; + } if ((was_warning || diagnostic->kind == DK_WARNING) && ((!m_warn_system_headers @@ -1434,9 +1476,28 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) inlining stack (if there is one) are in system headers. */ return false; + if (diagnostic->kind == DK_NOTE && notes_inhibited_in_group ()) + /* Bail for all the notes in the diagnostic_group that started to inhibit notes. */ + return false; + if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE) check_max_errors (false); + if (m_lock > 0) + { + /* If we're reporting an ICE in the middle of some other error, + try to flush out the previous error, then let this one + through. Don't do this more than once. */ + if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) + && m_lock == 1) + pp_newline_and_flush (m_reference_printer); + else + error_recursion (); + } + + /* We are accepting the diagnostic, so should stop inhibiting notes. */ + inhibit_notes_in_group (/*inhibit=*/false); + m_lock++; if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) @@ -1533,7 +1594,7 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic) || diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) action_after_output (diagnostic->kind); - diagnostic->x_data = NULL; + diagnostic->x_data = nullptr; if (m_edit_context_ptr) if (diagnostic->richloc->fixits_can_be_auto_applied_p ()) @@ -1563,6 +1624,14 @@ diagnostic_context::report_verbatim (text_info &text) } } +void +diagnostic_context:: +report_global_digraph (const diagnostics::digraphs::lazy_digraph &ldg) +{ + for (auto sink : m_output_sinks) + sink->report_global_digraph (ldg); +} + /* Get the number of digits in the decimal representation of VALUE. */ int @@ -1732,9 +1801,9 @@ fancy_abort (const char *file, int line, const char *function) /* Attempt to print a backtrace. */ struct backtrace_state *state - = backtrace_create_state (NULL, 0, bt_err_callback, NULL); + = backtrace_create_state (nullptr, 0, bt_err_callback, nullptr); int count = 0; - if (state != NULL) + if (state != nullptr) backtrace_full (state, 2, bt_callback, bt_err_callback, (void *) &count); @@ -1770,6 +1839,8 @@ diagnostic_context::end_group () sink->on_end_group (); m_diagnostic_groups.m_emission_count = 0; } + /* We're popping one level, so might need to stop inhibiting notes. */ + inhibit_notes_in_group (/*inhibit=*/false); } void @@ -1782,6 +1853,8 @@ void diagnostic_context::pop_nesting_level () { --m_diagnostic_groups.m_diagnostic_nesting_level; + /* We're popping one level, so might need to stop inhibiting notes. */ + inhibit_notes_in_group (/*inhibit=*/false); } void @@ -1807,6 +1880,7 @@ diagnostic_output_format_init (diagnostic_context &context, enum diagnostics_output_format format, bool json_formatting) { + diagnostic_output_format *new_sink = nullptr; switch (format) { default: @@ -1815,39 +1889,26 @@ diagnostic_output_format_init (diagnostic_context &context, /* The default; do nothing. */ break; - case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR: - diagnostic_output_format_init_json_stderr (context, - json_formatting); - break; - - case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE: - diagnostic_output_format_init_json_file (context, - json_formatting, - base_file_name); - break; - case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR: - diagnostic_output_format_init_sarif_stderr (context, - line_table, - main_input_filename_, - json_formatting, - sarif_version::v2_1_0); + new_sink = &diagnostic_output_format_init_sarif_stderr (context, + line_table, + json_formatting); break; case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE: - diagnostic_output_format_init_sarif_file (context, - line_table, - main_input_filename_, - json_formatting, - sarif_version::v2_1_0, - base_file_name); + new_sink = &diagnostic_output_format_init_sarif_file (context, + line_table, + json_formatting, + base_file_name); break; } + if (new_sink) + new_sink->set_main_input_filename (main_input_filename_); } /* Initialize this context's m_diagrams based on CHARSET. Specifically, make a text_art::theme object for m_diagrams.m_theme, - (or NULL for "no diagrams"). */ + (or nullptr for "no diagrams"). */ void diagnostic_context:: @@ -2172,7 +2233,7 @@ test_print_parseable_fixits_insert () linemap_add (line_table, LC_ENTER, false, "test.c", 0); linemap_line_start (line_table, 5, 100); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); + linemap_add (line_table, LC_LEAVE, false, nullptr, 0); location_t where = linemap_position_for_column (line_table, 10); richloc.add_fixit_insert_before (where, "added content"); @@ -2193,7 +2254,7 @@ test_print_parseable_fixits_remove () linemap_add (line_table, LC_ENTER, false, "test.c", 0); linemap_line_start (line_table, 5, 100); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); + linemap_add (line_table, LC_LEAVE, false, nullptr, 0); source_range where; where.m_start = linemap_position_for_column (line_table, 10); where.m_finish = linemap_position_for_column (line_table, 20); @@ -2216,7 +2277,7 @@ test_print_parseable_fixits_replace () linemap_add (line_table, LC_ENTER, false, "test.c", 0); linemap_line_start (line_table, 5, 100); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); + linemap_add (line_table, LC_LEAVE, false, nullptr, 0); source_range where; where.m_start = linemap_position_for_column (line_table, 10); where.m_finish = linemap_position_for_column (line_table, 20); @@ -2247,7 +2308,7 @@ test_print_parseable_fixits_bytes_vs_display_columns () linemap_add (line_table, LC_ENTER, false, fname, 0); linemap_line_start (line_table, 1, 100); - linemap_add (line_table, LC_LEAVE, false, NULL, 0); + linemap_add (line_table, LC_LEAVE, false, nullptr, 0); source_range where; where.m_start = linemap_position_for_column (line_table, 12); where.m_finish = linemap_position_for_column (line_table, 17); @@ -2305,7 +2366,7 @@ assert_location_text (const char *expected_loc_text, xloc.file = filename; xloc.line = line; xloc.column = column; - xloc.data = NULL; + xloc.data = nullptr; xloc.sysp = false; diagnostic_column_policy column_policy (dc); @@ -2321,7 +2382,7 @@ test_get_location_text () { const char *old_progname = progname; progname = "PROGNAME"; - assert_location_text ("PROGNAME:", NULL, 0, 0, true); + assert_location_text ("PROGNAME:", nullptr, 0, 0, true); char *built_in_colon = concat (special_fname_builtin (), ":", (char *) 0); assert_location_text (built_in_colon, special_fname_builtin (), 42, 10, true); |