diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-10-24 15:52:29 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-10-24 15:52:29 -0400 |
commit | ecd6bee0913db1237424ea68b0b1ec252b024e9c (patch) | |
tree | 5bd3d00a50f7c5bdc092409e25f18864b3ed0b9a /gcc/diagnostic-path.cc | |
parent | 097994003cb3b09af2b07238e54f08b89dd34369 (diff) | |
download | gcc-ecd6bee0913db1237424ea68b0b1ec252b024e9c.zip gcc-ecd6bee0913db1237424ea68b0b1ec252b024e9c.tar.gz gcc-ecd6bee0913db1237424ea68b0b1ec252b024e9c.tar.bz2 |
analyzer: avoid implicit use of global_dc's pretty_printer [PR116613]
Previously, various places in the analyzer generated message strings
by cloning the diagnostic_context's pretty_printer, printing to that
pretty_printer's buffer, and then returning a copy of the buffer
contents.
This implicit use of a particular pretty printer doesn't work well for
the "multiple diagnostic output formats" case (PR other/116613), such as
differences in colorization, or in how phase 3 of formatting works.
Hence as enabling work towards that, the following patch reworks the
various functions returning a label_text string in favor of functions
that print to a specific pretty_printer, such as diagnotic_event's
"get_desc" vfunc, which becomes "print_desc". This makes the particular
pretty_printer in use explicit in each case.
Previously, the various pending_diagnostic::describe_* vfuncs returned a
label_text, with the return of an empty string signifying that no
description could be generated. With this patch, these vfuncs gain a
"pretty_printer &" param and a bool return value and now either print to
the pretty_printer and return true, or return false to signify the
"no description available" case.
No functional change intended.
gcc/analyzer/ChangeLog:
PR other/116613
* bounds-checking.cc
(concrete_buffer_overflow::describe_final_event): Convert return
type from label_text to bool. Add "pp" param and either print to
it and return true, or return false.
(concrete_buffer_overflow::describe_final_event_as_bytes): Convert
to print to a pp rather than returning a label_text.
(concrete_buffer_overflow::describe_final_event_as_bits):
Likewise.
(class concrete_buffer_over_read): Analogous changes to above.
(class concrete_buffer_underwrite): Likewise.
(class concrete_buffer_under_read): Likewise.
(class symbolic_buffer_overflow): Likewise.
(class symbolic_buffer_over_read): Likewise.
* call-details.cc (class overlapping_buffers): Likewise.
* call-info.cc (call_info::print): Reimplement.
(class call_info::add_events_to_path::call_event): Convert
"get_desc" vfunc to "print_desc", dropping return type, adding
"pp" param, and printing to it.
(class succeed_or_fail_call_info): Likewise.
* call-info.h (class call_info): Likewise.
(class succeed_or_fail_call_info): Likewise.
* checker-event.cc (checker_event::dump): Reimplement.
(checker_event::prepare_for_emission): Update for change from
get_desc to print_desc.
(debug_event::get_desc): Convert to...
(debug_event::print_desc): ...this.
(precanned_custom_event::get_desc): Convert to...
(precanned_custom_event::print_desc): ...this.
(statement_event::get_desc): Convert to...
(statement_event::print_desc): ...this.
(region_creation_event_memory_space::get_desc): Convert to...
(region_creation_event_memory_space::print_desc): ...this.
(region_creation_event_capacity::get_desc): Convert to...
(region_creation_event_capacity::print_desc): ...this.
(region_creation_event_allocation_size::get_desc): Convert to...
(region_creation_event_allocation_size::print_desc): ...this.
(region_creation_event_debug::get_desc): Convert to...
(region_creation_event_debug::print_desc): ...this.
(function_entry_event::get_desc): Convert to...
(function_entry_event::print_desc): ...this.
(state_change_event::get_desc): Convert to...
(state_change_event::print_desc): ...this.
(state_change_event::get_meaning): Update for change to
pending_diagnostic::get_meaning_for_state_change.
(superedge_event::should_filter_p): Convert from usage of get_desc
to print_desc.
(start_cfg_edge_event::get_desc): Convert to...
(start_cfg_edge_event::print_desc): ...this.
(call_event::get_desc): Convert to...
(call_event::print_desc): ...this.
(return_event::get_desc): Convert to...
(return_event::print_desc): ...this.
(start_consolidated_cfg_edges_event::get_desc): Convert to...
(start_consolidated_cfg_edges_event::print_desc): ...this.
(inlined_call_event::get_desc): Convert to...
(inlined_call_event::print_desc): ...this.
(setjmp_event::get_desc): Convert to...
(setjmp_event::print_desc): ...this.
(rewind_from_longjmp_event::get_desc): Convert to...
(rewind_from_longjmp_event::print_desc): ...this.
(rewind_to_setjmp_event::get_desc): Convert to...
(rewind_to_setjmp_event::print_desc): ...this.
(warning_event::get_desc): Convert to...
(warning_event::print_desc): ...this.
* checker-event.h: Convert the various "get_desc" vfunc decls to
"print_desc".
* checker-path.cc (checker_path::dump): Convert to usage of
checker_event::print_desc.
(checker_path::debug): Convert to debug form of
checker_event::get_desc.
* diagnostic-manager.cc
(diagnostic_manager::prune_interproc_events): Likewise.
(diagnostic_manager::prune_system_headers): Likewise.
* engine.cc (call_summary_edge_info::get_desc): Convert to...
(call_summary_edge_info::print_desc): ...this.
(stale_jmp_buf::describe_final_event): Update for change to
this vfunc.
(tainted_args_function_custom_event::get_desc): Convert to...
(tainted_args_function_custom_event::print_desc): ...this.
(tainted_args_field_custom_event::get_desc): Convert to...
(tainted_args_field_custom_event::print_desc): ...this.
(tainted_args_callback_custom_event::get_desc): Convert to...
(tainted_args_callback_custom_event::print_desc): ...this.
(jump_through_null::describe_final_event): Update for change to
this vfunc.
* infinite-loop.cc (perpetual_start_cfg_edge_event::get_desc):
Convert to...
(perpetual_start_cfg_edge_event::print_desc): ...this.
(looping_back_event::get_desc): Convert to...
(looping_back_event::print_desc): ...this.
(looping_back_event::describe_final_event): Update for change to
this vfunc.
* infinite-recursion.cc (class infinite_recursion_diagnostic):
Update for changes to pending_diagnostic.
* kf.cc (class putenv_of_auto_var): Likewise.
(kf_realloc::impl_call_post): Update for changes to call_info.
(kf_strchr::impl_call_post): Likewise.
(kf_strncpy::impl_call_post): Likewise.
(kf_strstr::impl_call_post): Likewise.
(class kf_strtok::undefined_behavior): Update for changes to
pending_diagnostic.
(class strtok_call_info): Update for changes to call_info.
* pending-diagnostic.cc (evdesc::event_desc::formatted_print):
Delete.
* pending-diagnostic.h (struct event_desc): Delete.
(struct state_change): Drop event_desc base class.
(struct call_with_state): Likewise.
(struct return_of_state): Likewise.
(struct final_event): Likewise.
(pending_event::describe_state_change): Convert return
type from label_text to bool. Add "pp" param and either print to
it and return true, or return false. Do the latter for the base
class implementation.
(pending_event::describe_call_with_state): Likewise.
(pending_event::describe_return_of_state): Likewise.
(pending_event::describe_final_event): Likewise.
* region-model.cc
(poisoned_value_diagnostic::describe_final_event): Update for
change to this vfunc.
(shift_count_negative_diagnostic::describe_final_event): Likewise.
(shift_count_overflow_diagnostic::describe_final_event): Likewise.
(ptrdiff_region_creation_event::get_desc): Convert to...
(ptrdiff_region_creation_event::print_desc): ...this.
(undefined_ptrdiff_diagnostic::describe_final_event): Update for
change to this vfunc.
(write_to_const_diagnostic::describe_final_event): Likewise.
(write_to_string_literal_diagnostic::describe_final_event):
Likewise.
(dubious_allocation_size::describe_final_event): Likewise.
(null_terminator_check_event::get_desc): Convert to...
(null_terminator_check_event::print_desc): ...this.
(float_as_size_arg::describe_final_event): Update for change to
this vfunc.
(exposure_through_uninit_copy::describe_final_event): Likewise.
* sm-fd.cc: Include "diagnostic-core.h". Update throughout for
changes to pending_diagnostic vfuncs.
* sm-file.cc: Likewise.
* sm-malloc.cc: Likewise.
* sm-sensitive.cc: Likewise.
* sm-signal.cc: Likewise.
* sm-taint.cc: Likewise.
* varargs.cc: Likewise.
gcc/ChangeLog:
PR other/116613
* diagnostic-format-json.cc (make_json_for_path): Add "ref_pp"
param and use when obtaining event descriptions.
(json_output_format::on_report_diagnostic): Pass this format's
printer as the above.
* diagnostic-format-sarif.cc
(sarif_builder::make_location_object): Clone this format's printer
and use it to obtain the text of the message.
* diagnostic-path.cc: Include "pretty-print-markup.h".
(diagnostic_event::get_desc): New.
(path_label::get_text): Update for changes to diagnostic_event.
(event_range::print): Likewise.
(class element_event_desc): New.
(diagnostic_text_output_format::print_path): Update for changes to
diagnostic_event.
* diagnostic-path.h (diagnostic_event::get_desc): Replace with...
(diagnostic_event::print_desc): ...this.
(diagnostic_event::get_desc): Add this back for debugging, without
the bool param.
* pretty-print.cc (pp_printf_n): New.
* pretty-print.h (pp_printf_n): New decl.
* selftest-diagnostic-path.h (test_diagnostic_event::get_desc):
Convert to...
(test_diagnostic_event::print_desc): ...this.
* simple-diagnostic-path.cc (simple_diagnostic_event::print_desc):
New.
(selftest::test_intraprocedural_path): Use debug form of get_desc.
* simple-diagnostic-path.h (simple_diagnostic_event::get_desc):
Convert to...
(simple_diagnostic_event::print_desc): ...this, moving
implementation to test_diagnostic_event.
gcc/testsuite/ChangeLog:
PR other/116613
* gcc.dg/plugin/analyzer_cpython_plugin.c: Convert call outcomes
from "get_desc" to print_desc".
* gcc.dg/plugin/analyzer_gil_plugin.c: Update for changes to
pending_diagnostic vfuncs.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-path.cc')
-rw-r--r-- | gcc/diagnostic-path.cc | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/gcc/diagnostic-path.cc b/gcc/diagnostic-path.cc index 2c42807..8a6d516 100644 --- a/gcc/diagnostic-path.cc +++ b/gcc/diagnostic-path.cc @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-color.h" #include "diagnostic-event-id.h" #include "diagnostic-label-effects.h" +#include "pretty-print-markup.h" #include "selftest.h" #include "selftest-diagnostic.h" #include "selftest-diagnostic-path.h" @@ -154,6 +155,18 @@ diagnostic_event::meaning::maybe_get_property_str (enum property p) } } +/* Generate a label_text containing the description of this event + (for debugging/logging purposes). */ + +label_text +diagnostic_event::get_desc () const +{ + auto pp = global_dc->clone_printer (); + pp_show_color (pp.get ()) = false; + print_desc (*pp.get ()); + return label_text::take (xstrdup (pp_formatted_text (pp.get ()))); +} + /* class diagnostic_path. */ /* Subroutine of diagnostic_path::interprocedural_p. @@ -261,38 +274,33 @@ class path_label : public range_label unsigned event_idx = m_start_idx + range_idx; const diagnostic_event &event = m_path.get_event (event_idx); - /* Get the description of the event, perhaps with colorization: - normally, we don't colorize within a range_label, but this - is special-cased for diagnostic paths. */ - label_text event_text (event.get_desc (m_colorize)); - gcc_assert (event_text.get ()); - const diagnostic_event::meaning meaning (event.get_meaning ()); - pretty_printer pp; - pp_show_color (&pp) = m_colorize; + auto pp = global_dc->clone_printer (); + pp_show_color (pp.get ()) = m_colorize; diagnostic_event_id_t event_id (event_idx); - pp_printf (&pp, "%@", &event_id); - pp_space (&pp); + pp_printf (pp.get (), "%@", &event_id); + pp_space (pp.get ()); if (meaning.m_verb == diagnostic_event::VERB_danger && m_allow_emojis) { - pp_unicode_character (&pp, 0x26A0); /* U+26A0 WARNING SIGN. */ + pp_unicode_character (pp.get (), 0x26A0); /* U+26A0 WARNING SIGN. */ /* Append U+FE0F VARIATION SELECTOR-16 to select the emoji variation of the char. */ - pp_unicode_character (&pp, 0xFE0F); + pp_unicode_character (pp.get (), 0xFE0F); /* U+26A0 WARNING SIGN has East_Asian_Width == Neutral, but in its emoji variant is printed (by vte at least) with a 2nd half overlapping the next char. Hence we add two spaces here: a space to be covered by this overlap, plus another space of padding. */ - pp_string (&pp, " "); + pp_string (pp.get (), " "); } - pp_printf (&pp, "%s", event_text.get ()); + event.print_desc (*pp.get ()); - label_text result = label_text::take (xstrdup (pp_formatted_text (&pp))); + label_text result + = label_text::take (xstrdup (pp_formatted_text (pp.get ()))); return result; } @@ -667,8 +675,8 @@ struct event_range { const diagnostic_event &iter_event = m_path.get_event (i); diagnostic_event_id_t event_id (i); - label_text event_text (iter_event.get_desc (true)); - pp_printf (&pp, " %@: %s", &event_id, event_text.get ()); + pp_printf (&pp, " %@: ", &event_id); + iter_event.print_desc (pp); pp_newline (&pp); } return; @@ -1102,6 +1110,25 @@ print_path_summary_as_text (const path_summary &ps, } /* end of anonymous namespace for path-printing code. */ +class element_event_desc : public pp_element +{ +public: + element_event_desc (const diagnostic_event &event) + : m_event (event) + { + } + + void add_to_phase_2 (pp_markup::context &ctxt) final override + { + auto pp = ctxt.m_pp.clone (); + m_event.print_desc (*pp.get ()); + pp_string (&ctxt.m_pp, pp_formatted_text (pp.get ())); + } + +private: + const diagnostic_event &m_event; +}; + /* Print PATH according to the context's path_format. */ void @@ -1121,8 +1148,7 @@ diagnostic_text_output_format::print_path (const diagnostic_path &path) for (unsigned i = 0; i < num_events; i++) { const diagnostic_event &event = path.get_event (i); - label_text event_text (event.get_desc (false)); - gcc_assert (event_text.get ()); + element_event_desc e_event_desc (event); diagnostic_event_id_t event_id (i); if (get_context ().show_path_depths_p ()) { @@ -1135,19 +1161,19 @@ diagnostic_text_output_format::print_path (const diagnostic_path &path) { label_text name (logical_loc->get_name_for_path_output ()); inform (event.get_location (), - "%@ %s (fndecl %qs, depth %i)", - &event_id, event_text.get (), + "%@ %e (fndecl %qs, depth %i)", + &event_id, &e_event_desc, name.get (), stack_depth); } else inform (event.get_location (), - "%@ %s (depth %i)", - &event_id, event_text.get (), + "%@ %e (depth %i)", + &event_id, &e_event_desc, stack_depth); } else inform (event.get_location (), - "%@ %s", &event_id, event_text.get ()); + "%@ %e", &event_id, &e_event_desc); } } break; |