From 3dcce649a1e0833a4c3bb9ced4b9c0b38c3fb8a5 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 10 Jun 2025 20:06:37 -0400 Subject: [PATCH] diagnostics: fix tag nesting issues in experimental-html sink [PR120610] I've been seeing issues in the experimental-html sink where the nesting of tags goes wrong. The two issues I've seen are: * the pp_token_list from the diagnostic message that reaches the html_token_printer doesn't always have matching pairs of begin/end tokens (PR other/120610) * a bug in diagnostic-show-locus where there was a stray xp.pop_tag, in print_trailing_fixits. This patch: * changes the xml::printer::pop_tag API so that it now takes the expected name of the element being popped (rather than expressing this in comments), and that, by default, the xml::printer asserts that this matches. * gives the html_token_printer its own xml::printer instance to restrict the affected area of the DOM tree; this xml::printer doesn't enforce nesting (PR other/120610) * adds RAII sentinel classes that automatically check for pushes/pops being balanced within a scope, using them in various places * fixes the bug in print_trailing_fixits for html output gcc/ChangeLog: PR other/120610 * diagnostic-format-html.cc (html_builder::html_builder): Update for new param of xml::printer::pop_tag. (html_path_label_writer::end_label): Likewise. (html_builder::make_element_for_diagnostic::html_token_printer): Give the instance its own xml::printer. Update for new param of xml::printer::pop_tag. (html_builder::make_element_for_diagnostic): Give the instance its own xml::printer. (html_builder::make_metadata_element): Update for new param of xml::printer::pop_tag. (html_builder::flush_to_file): Likewise. * diagnostic-path-output.cc (begin_html_stack_frame): Likewise. (begin_html_stack_frame): Likewise. (end_html_stack_frame): Likewise. (print_path_summary_as_html): Likewise. * diagnostic-show-locus.cc (struct to_text::auto_check_tag_nesting): New. (struct to_html:: auto_check_tag_nesting): New. (to_text::pop_html_tag): Change param to const char *. (to_html::pop_html_tag): Likewise; rename param to "expected_name". (default_diagnostic_start_span_fn): Update for new param of xml::printer::pop_tag. (layout_printer::end_label): Likewise. (layout_printer::print_trailing_fixits): Add RAII sentinel to check tag nesting for the HTML case. Delete stray popping of "td" in the presence of fix-it hints. (layout_printer::print_line): Add RAII sentinel to check tag nesting for the HTML case. (diagnostic_source_print_policy::print_as_html): Likewise. (layout_printer::print): Likewise. * xml-printer.h (xml::printer::printer): Add optional "check_popped_tags" param. (xml::printer::pop_tag): Add "expected_name" param. (xml::printer::get_num_open_tags): New accessor. (xml::printer::dump): New decl. (xml::printer::m_check_popped_tags): New field. (class xml::auto_check_tag_nesting): New. (class xml::auto_print_element): Update for new param of pop_tag. * xml.cc: Move pragma pop so that the pragma also covers xml::printer's member functions, "dump" in particular. (xml::printer::printer): Add param "check_popped_tags". (xml::printer::pop_tag): Add param "expected_name" and use it to assert that the popped tag is as expected. Assert that we have a tag to pop. (xml::printer::dump): New. (selftest::test_printer): Update for new param of pop_tag. (selftest::test_attribute_ordering): Likewise. gcc/testsuite/ChangeLog: PR other/120610 * gcc.dg/format/diagnostic-ranges-html.py: Remove out-of-date comment. Signed-off-by: David Malcolm --- gcc/diagnostic-format-html.cc | 29 +++++++----- gcc/diagnostic-path-output.cc | 28 +++++------ gcc/diagnostic-show-locus.cc | 36 +++++++++++---- .../gcc.dg/format/diagnostic-ranges-html.py | 23 ---------- gcc/xml-printer.h | 41 +++++++++++++++-- gcc/xml.cc | 46 ++++++++++++++----- 6 files changed, 131 insertions(+), 72 deletions(-) diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index ddf6ba0f4cf..6010712b8a5 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -382,7 +382,7 @@ html_builder::html_builder (diagnostic_context &context, /* Escaping rules are different for HTML