diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-10-23 10:54:42 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-10-23 10:54:42 -0400 |
commit | f565063a0602ad3b48ac687f575dea7a90cd4105 (patch) | |
tree | 3cd13dc9544d4111e590d5b29e4b60c3ea6436b6 /gcc/fortran | |
parent | de2dc62379b7a2c93e11b03804380af072fd249b (diff) | |
download | gcc-f565063a0602ad3b48ac687f575dea7a90cd4105.zip gcc-f565063a0602ad3b48ac687f575dea7a90cd4105.tar.gz gcc-f565063a0602ad3b48ac687f575dea7a90cd4105.tar.bz2 |
diagnostics: implement buffering for non-textual formats [PR105916]
PR fortran/105916 reports stray diagnostics appearing in JSON and SARIF
output from gfortran.
In order to handle various awkard parsing issues, the Fortran frontend
implements buffering of diagnostics, so that diagnostics reported to
global_dc can be either:
(a) immediately issued, or
(b) speculatively reported to global_dc, and stored in a buffer, to
either be issued later or discarded.
This buffering code in gcc/fortran/error.cc directly manipulates
implementation details of the diagnostic_context such as the
pretty_printer's buffer, and the counts of how many diagnostics have
been issued. The issue is that this manipulation of pretty_printer's
buffer doesn't work for formats such as JSON and SARIF where diagnostics
are handled in a different way (such as by accumulating json::object
instances in an array).
This patch moves responsibility for such buffering of diagnostics from
fortran's error.cc to the diagnostic subsystem. It introduces a new
class diagnostic_buffer representing a particular buffer of diagnostics
that have been reported but not yet issued. Each diagnostic output
format implements buffering in a different way, and so there is a
new class hierarchy, diagnostic_per_format_buffer, representing the
various format-specific ways that buffering is to be implemented. This
is hidden as an implementation detail of diagnostic_buffer.
The patch also updates how diagnostics of each kind (e.g. warnings vs
errors) are counted, so that if buffering is enabled, the count is
incremented within the buffer, and the counts in the diagnostic_context
are only updated if and when the buffer is flushed; checking for
max_errors is similarly updated to support both buffered and unbuffered
cases.
For ease of debugging, the patch extends the "dump" functions within the
diagnostics subsystem, so that e.g. global_dc->dump () now prints the
buffering status, e.g.:
(gdb) call global_dc->dump()
diagnostic_context:
counts:
(none)
output format:
sarif_output_format
printer:
m_show_color: false
m_url_format: bel
m_buffer:
m_formatted_obstack current object: length 0:
m_chunk_obstack current object: length 0:
diagnostic buffer:
m_per_format_buffer:
counts:
error: 1
diagnostic_sarif_format_buffer:
result[0]:
{"ruleId": "error",
"level": "error",
"message": {"text": "Function ‘program’ requires an argument list at (1)"},
"locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../src/gcc/testsuite/gfortran.dg/pr105954.f90",
"uriBaseId": "PWD"},
"region": {"startLine": 6,
"startColumn": 8,
"endColumn": 9},
"contextRegion": {"startLine": 6,
"snippet": {"text": "program p\n"}}}}]}
which shows that no diagnostics have been issued yet, but the active
diagnostic_buffer has a single error buffered within it, in SARIF form.
Similarly, it's possible to use "dump" on a diagnostic_buffer to directly
query its contents; here's the same example, this time with the text
output format:
(gdb) call error_buffer.buffer.dump()
m_per_format_buffer:
counts:
error: 1
diagnostic_text_format_buffer:
m_formatted_obstack current object: length 232:
00000000: 1b 5b 30 31 6d 1b 5b 4b 2e 2e 2f 2e 2e 2f 73 72 | .[01m.[K../../sr
00000010: 63 2f 67 63 63 2f 74 65 73 74 73 75 69 74 65 2f | c/gcc/testsuite/
00000020: 67 66 6f 72 74 72 61 6e 2e 64 67 2f 70 72 31 30 | gfortran.dg/pr10
00000030: 35 39 35 34 2e 66 39 30 3a 36 3a 38 3a 1b 5b 6d | 5954.f90:6:8:.[m
00000040: 1b 5b 4b 0a 0a 20 20 20 20 36 20 7c 20 70 72 6f | .[K.. 6 | pro
00000050: 67 72 61 6d 20 70 0a 20 20 20 20 20 20 7c 20 20 | gram p. |
00000060: 20 20 20 20 20 20 1b 5b 30 31 3b 33 31 6d 1b 5b | .[01;31m.[
00000070: 4b 31 1b 5b 6d 1b 5b 4b 0a 1b 5b 30 31 3b 33 31 | K1.[m.[K..[01;31
00000080: 6d 1b 5b 4b 45 72 72 6f 72 3a 1b 5b 6d 1b 5b 4b | m.[KError:.[m.[K
00000090: 20 46 75 6e 63 74 69 6f 6e 20 e2 80 98 1b 5b 30 | Function ....[0
000000a0: 31 6d 1b 5b 4b 70 72 6f 67 72 61 6d 1b 5b 6d 1b | 1m.[Kprogram.[m.
000000b0: 5b 4b e2 80 99 20 72 65 71 75 69 72 65 73 20 61 | [K... requires a
000000c0: 6e 20 61 72 67 75 6d 65 6e 74 20 6c 69 73 74 20 | n argument list
000000d0: 61 74 20 1b 5b 30 31 3b 33 31 6d 1b 5b 4b 28 31 | at .[01;31m.[K(1
000000e0: 29 1b 5b 6d 1b 5b 4b 0a | ).[m.[K.
m_chunk_obstack current object: length 0:
showing that we have an error in error_buffer, with colorized text.
gcc/ChangeLog:
PR fortran/105916
* diagnostic-buffer.h: New file.
* diagnostic-format-json.cc: Define INCLUDE_VECTOR. Include
"diagnostic-buffer.h".
(class diagnostic_json_format_buffer): New subclass.
(class json_output_format): Add friend class
diagnostic_json_format_buffer.
(json_output_format::make_per_format_buffer): New vfunc
implementation.
(json_output_format::set_buffer): New vfunc implementation.
(json_output_format::json_output_format): Initialize m_buffer.
(json_output_format::m_buffer): New field.
(diagnostic_json_format_buffer::dump): New.
(diagnostic_json_format_buffer::empty_p): New.
(diagnostic_json_format_buffer::move_to): New.
(diagnostic_json_format_buffer::clear): New.
(diagnostic_json_format_buffer::flush): New.
(json_output_format::on_report_diagnostic): Implement optional
buffering.
* diagnostic-format-sarif.cc: Include "diagnostic-buffer.h".
(class diagnostic_sarif_format_buffer): New subclass.
(class sarif_builder): Add friend
class diagnostic_sarif_format_buffer.
(sarif_builder::num_results): New accessor.
(sarif_builder::get_result): New accessor.
(sarif_builder::on_report_diagnostic): Add param "buffer"; use it
to implement optional buffering.
(diagnostic_sarif_format_buffer::dump): New.
(diagnostic_sarif_format_buffer::empty_p): New.
(diagnostic_sarif_format_buffer::move_to): New.
(diagnostic_sarif_format_buffer::clear): New.
(diagnostic_sarif_format_buffer::flush): New.
(sarif_output_format::make_per_format_buffer): New vfunc
implementation.
(sarif_output_format::set_buffer): New vfunc implementation.
(sarif_output_format::on_report_diagnostic): Pass m_buffer to
sarif_builder::on_report_diagnostic.
(sarif_output_format::num_results): New accessor.
(sarif_output_format::get_result): New accessor.
(diagnostic_output_format::diagnostic_output_format): Initialize
m_buffer.
(diagnostic_output_format::m_buffer): New field.
(diagnostic_output_format::num_results): Get accessor.
(diagnostic_output_format::get_result): Get accessor.
(selftest::get_message_from_result): New.
(selftest::test_buffering): New.
(selftest::diagnostic_format_sarif_cc_tests): Call it.
* diagnostic-format-text.cc: Include
"diagnostic-client-data-hooks.h".
(class diagnostic_text_format_buffer): New subclass.
(diagnostic_text_format_buffer::diagnostic_text_format_buffer):
New.
(diagnostic_text_format_buffer::dump): New.
(diagnostic_text_format_buffer::empty_p): New.
(diagnostic_text_format_buffer::move_to): New.
(diagnostic_text_format_buffer::clear): New.
(diagnostic_text_format_buffer::flush): New.
(diagnostic_text_output_format::dump): Dump m_saved_output_buffer.
(diagnostic_text_output_format::set_buffer): New.
(diagnostic_text_output_format::make_per_format_buffer): New.
* diagnostic-format-text.h
(diagnostic_text_output_format::diagnostic_text_output_format):
Initialize m_saved_output_buffer.
(diagnostic_text_output_format::set_buffer): New decl.
(diagnostic_text_output_format::make_per_format_buffer): New decl.
(diagnostic_text_output_format::m_saved_output_buffer): New field.
* diagnostic-format.h (class diagnostic_per_format_buffer): New
forward decl.
(diagnostic_output_format::make_per_format_buffer): New vfunc.
(diagnostic_output_format::set_buffer): New vfunc.
* diagnostic.cc: Include "diagnostic-buffer.h".
(diagnostic_context::initialize): Replace memset with call to
"clear" on m_diagnostic_counters. Initializer
m_diagnostic_buffer.
(diagnostic_context::finish): Call set_diagnostic_buffer with
nullptr.
(diagnostic_context::dump): Update for encapsulation of counts
into m_diagnostic_counters. Dump m_diagnostic_buffer.
(diagnostic_context::execution_failed_p): Update for encapsulation of
counts into m_diagnostic_counters.
(diagnostic_context::check_max_errors): Likewise.
(diagnostic_context::report_diagnostic): Likewise. Eliminate
diagnostic_check_max_errors in favor of check_max_errors.
Update increment of counter to support buffering. Eliminate
diagnostic_action_after_output in favor of action_after_output.
Only add fixits to m_edit_context_ptr if buffering is disabled.
Only call diagnostic_output_format::after_diagnostic if buffering
is disabled.
(diagnostic_context::error_recursion): Eliminate
diagnostic_action_after_output in favor of action_after_output.
(diagnostic_context::set_diagnostic_buffer): New.
(diagnostic_context::clear_diagnostic_buffer): New.
(diagnostic_context::flush_diagnostic_buffer): New.
(diagnostic_counters::diagnostic_counters): New.
(diagnostic_counters::dump): New.
(diagnostic_counters::move_to): New.
(diagnostic_counters::clear): New.
(diagnostic_buffer::diagnostic_buffer): New.
(diagnostic_buffer::~diagnostic_buffer): New.
(diagnostic_buffer::dump): New.
(diagnostic_buffer::empty_p): New.
(diagnostic_buffer::move_to): New.
(diagnostic_buffer::ensure_per_format_buffer): New.
(c_diagnostic_cc_tests): Remove stray newline.
* diagnostic.h (class diagnostic_buffer): New forward decl.
(struct diagnostic_counters): New.
(diagnostic_context::check_max_errors): Make private.
(diagnostic_context::action_after_output): Make private.
(diagnostic_context::get_output_format): Make non-const.
(diagnostic_context::diagnostic_count): Update for change
to m_diagnostic_counters.
(diagnostic_context::set_diagnostic_buffer): New decl.
(diagnostic_context::get_diagnostic_buffer): New decl.
(diagnostic_context::clear_diagnostic_buffer): New decl.
(diagnostic_context::flush_diagnostic_buffer): New decl.
(diagnostic_context::m_diagnostic_count): Replace array with...
(diagnostic_context::m_diagnostic_counters): ...this.
(diagnostic_context::m_diagnostic_buffer): New field.
(diagnostic_action_after_output): Delete.
(diagnostic_check_max_errors): Delete.
gcc/fortran/ChangeLog:
PR fortran/105916
* error.cc (pp_error_buffer, pp_warning_buffer): Convert from
output_buffer * to diagnostic_buffer *.
(warningcount_buffered, werrorcount_buffered): Eliminate.
(gfc_error_buffer::gfc_error_buffer): Move constructor definition
here, and initialize "buffer" using *global_dc.
(gfc_output_buffer_empty_p): Delete in favor of
diagnostic_buffer::empty_p.
(gfc_clear_pp_buffer): Replace with...
(gfc_clear_diagnostic_buffer): ...this, moving implementation
details to diagnostic_context::clear_diagnostic_buffer.
(gfc_warning): Replace buffering implementation with calls
to global_dc->get_diagnostic_buffer and
global_dc->set_diagnostic_buffer.
(gfc_clear_warning): Update for renaming of gfc_clear_pp_buffer
and elimination of warningcount_buffered and werrorcount_buffered.
(gfc_warning_check): Replace buffering implementation with calls
to pp_warning_buffer->empty_p and
global_dc->flush_diagnostic_buffer.
(gfc_error_opt): Replace buffering implementation with calls to
global_dc->get_diagnostic_buffer and set_diagnostic_buffer.
(gfc_clear_error): Update for renaming of gfc_clear_pp_buffer.
(gfc_error_flag_test): Replace call to gfc_output_buffer_empty_p
with call to diagnostic_buffer::empty_p.
(gfc_error_check): Replace buffering implementation with calls
to pp_error_buffer->empty_p and global_dc->flush_diagnostic_buffer.
(gfc_move_error_buffer_from_to): Replace buffering implementation
with usage of diagnostic_buffer.
(gfc_free_error): Update for renaming of gfc_clear_pp_buffer.
(gfc_diagnostics_init): Use "new" directly when creating
pp_warning_buffer. Remove setting of m_flush_p on the two
buffers, as this is handled by diagnostic_buffer and by
diagnostic_text_format_buffer's constructor.
* gfortran.h: Replace #include "pretty-print.h" for output_buffer
with #include "diagnostic-buffer.h" for diagnostic_buffer.
(struct gfc_error_buffer): Change type of field "buffer" from
output_buffer to diagnostic_buffer. Move definition of constructor
into error.cc so that it can use global_dc.
gcc/testsuite/ChangeLog:
PR fortran/105916
* gcc.dg/plugin/diagnostic_plugin_xhtml_format.c: Include
"diagnostic-buffer.h".
(class diagnostic_xhtml_format_buffer): New subclass.
(class xhtml_builder): Add friend
class diagnostic_xhtml_format_buffer.
(diagnostic_xhtml_format_buffer::dump): New.
(diagnostic_xhtml_format_buffer::empty_p): New.
(diagnostic_xhtml_format_buffer::move_to): New.
(diagnostic_xhtml_format_buffer::clear): New.
(diagnostic_xhtml_format_buffer::flush): New.
(xhtml_builder::on_report_diagnostic): Add "buffer" param, and use
it.
(xhtml_output_format::dump): Fix typo.
(xhtml_output_format::make_per_format_buffer): New.
(xhtml_output_format::set_buffer): New.
(xhtml_output_format::on_report_diagnostic): Fix whitespace. Pass
m_buffer to xhtml_builder::on_report_diagnostic.
(xhtml_output_format::xhtml_output_format): Initialize m_buffer.
(xhtml_output_format::m_buffer): New field.
* gfortran.dg/diagnostic-format-json-pr105916.F90: New test.
* gfortran.dg/diagnostic-format-sarif-1.F90: New test.
* gfortran.dg/diagnostic-format-sarif-1.py: New support script.
* gfortran.dg/diagnostic-format-sarif-pr105916.f90: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/error.cc | 149 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 7 |
2 files changed, 40 insertions, 116 deletions
diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc index b27cbed..64e1ce5 100644 --- a/gcc/fortran/error.cc +++ b/gcc/fortran/error.cc @@ -43,11 +43,12 @@ static bool warnings_not_errors = false; static bool buffered_p; static gfc_error_buffer error_buffer; -/* These are always buffered buffers (.flush_p == false) to be used by - the pretty-printer. */ -static output_buffer *pp_error_buffer, *pp_warning_buffer; -static int warningcount_buffered, werrorcount_buffered; +static diagnostic_buffer *pp_error_buffer, *pp_warning_buffer; +gfc_error_buffer::gfc_error_buffer () +: flag (false), buffer (*global_dc) +{ +} /* Return a location_t suitable for 'tree' for a gfortran locus. During parsing in gfortran, loc->u.lb->location contains only the line number @@ -96,14 +97,6 @@ gfc_buffered_p (void) return buffered_p; } -/* Return true if there output_buffer is empty. */ - -static bool -gfc_output_buffer_empty_p (const output_buffer * buf) -{ - return output_buffer_last_position_in_text (buf) == NULL; -} - /* Go one level deeper suppressing errors. */ void @@ -231,19 +224,14 @@ gfc_print_wide_char (gfc_char_t c) } -/* Clear any output buffered in a pretty-print output_buffer. */ +/* Clear any output buffered in THIS_BUFFER without issuing + it to global_dc. */ static void -gfc_clear_pp_buffer (output_buffer *this_buffer) +gfc_clear_diagnostic_buffer (diagnostic_buffer *this_buffer) { - pretty_printer *pp = global_dc->m_printer; - output_buffer *tmp_buffer = pp_buffer (pp); - pp_buffer (pp) = this_buffer; - pp_clear_output_area (pp); - pp_buffer (pp) = tmp_buffer; - /* We need to reset last_location, otherwise we may skip caret lines - when we actually give a diagnostic. */ - global_dc->m_last_location = UNKNOWN_LOCATION; + gcc_assert (this_buffer); + global_dc->clear_diagnostic_buffer (*this_buffer); } /* The currently-printing diagnostic, for use by gfc_format_decoder, @@ -275,19 +263,13 @@ gfc_warning (int opt, const char *gmsgid, va_list ap) diagnostic_info diagnostic; rich_location rich_loc (line_table, UNKNOWN_LOCATION); - bool fatal_errors = global_dc->m_fatal_errors; - pretty_printer *pp = global_dc->m_printer; - output_buffer *tmp_buffer = pp_buffer (pp); + diagnostic_buffer *old_buffer = global_dc->get_diagnostic_buffer (); + gcc_assert (!old_buffer); - gfc_clear_pp_buffer (pp_warning_buffer); + gfc_clear_diagnostic_buffer (pp_warning_buffer); if (buffered_p) - { - pp_buffer (pp) = pp_warning_buffer; - global_dc->m_fatal_errors = false; - /* To prevent -fmax-errors= triggering. */ - --werrorcount; - } + global_dc->set_diagnostic_buffer (pp_warning_buffer); diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_WARNING); @@ -295,21 +277,7 @@ gfc_warning (int opt, const char *gmsgid, va_list ap) bool ret = gfc_report_diagnostic (&diagnostic); if (buffered_p) - { - pp_buffer (pp) = tmp_buffer; - global_dc->m_fatal_errors = fatal_errors; - - warningcount_buffered = 0; - werrorcount_buffered = 0; - /* Undo the above --werrorcount if not Werror, otherwise - werrorcount is correct already. */ - if (!ret) - ++werrorcount; - else if (diagnostic.kind == DK_ERROR) - ++werrorcount_buffered; - else - ++werrorcount, --warningcount, ++warningcount_buffered; - } + global_dc->set_diagnostic_buffer (old_buffer); va_end (argp); return ret; @@ -769,9 +737,7 @@ gfc_fatal_error (const char *gmsgid, ...) void gfc_clear_warning (void) { - gfc_clear_pp_buffer (pp_warning_buffer); - warningcount_buffered = 0; - werrorcount_buffered = 0; + gfc_clear_diagnostic_buffer (pp_warning_buffer); } @@ -781,21 +747,8 @@ gfc_clear_warning (void) void gfc_warning_check (void) { - if (! gfc_output_buffer_empty_p (pp_warning_buffer)) - { - pretty_printer *pp = global_dc->m_printer; - output_buffer *tmp_buffer = pp_buffer (pp); - pp_buffer (pp) = pp_warning_buffer; - pp_really_flush (pp); - warningcount += warningcount_buffered; - werrorcount += werrorcount_buffered; - gcc_assert (warningcount_buffered + werrorcount_buffered == 1); - pp_buffer (pp) = tmp_buffer; - diagnostic_action_after_output (global_dc, - warningcount_buffered - ? DK_WARNING : DK_ERROR); - diagnostic_check_max_errors (global_dc, true); - } + if (! pp_warning_buffer->empty_p ()) + global_dc->flush_diagnostic_buffer (*pp_warning_buffer); } @@ -806,7 +759,6 @@ gfc_error_opt (int opt, const char *gmsgid, va_list ap) { va_list argp; va_copy (argp, ap); - bool saved_abort_on_error = false; if (warnings_not_errors) { @@ -823,35 +775,19 @@ gfc_error_opt (int opt, const char *gmsgid, va_list ap) diagnostic_info diagnostic; rich_location richloc (line_table, UNKNOWN_LOCATION); - bool fatal_errors = global_dc->m_fatal_errors; - pretty_printer *pp = global_dc->m_printer; - output_buffer *tmp_buffer = pp_buffer (pp); + diagnostic_buffer *old_buffer = global_dc->get_diagnostic_buffer (); + gcc_assert (!old_buffer); - gfc_clear_pp_buffer (pp_error_buffer); + gfc_clear_diagnostic_buffer (pp_error_buffer); if (buffered_p) - { - /* To prevent -dH from triggering an abort on a buffered error, - save abort_on_error and restore it below. */ - saved_abort_on_error = global_dc->m_abort_on_error; - global_dc->m_abort_on_error = false; - pp_buffer (pp) = pp_error_buffer; - global_dc->m_fatal_errors = false; - /* To prevent -fmax-errors= triggering, we decrease it before - report_diagnostic increases it. */ - --errorcount; - } + global_dc->set_diagnostic_buffer (pp_error_buffer); diagnostic_set_info (&diagnostic, gmsgid, &argp, &richloc, DK_ERROR); gfc_report_diagnostic (&diagnostic); if (buffered_p) - { - pp_buffer (pp) = tmp_buffer; - global_dc->m_fatal_errors = fatal_errors; - global_dc->m_abort_on_error = saved_abort_on_error; - - } + global_dc->set_diagnostic_buffer (old_buffer); va_end (argp); } @@ -907,7 +843,7 @@ gfc_clear_error (void) { error_buffer.flag = false; warnings_not_errors = false; - gfc_clear_pp_buffer (pp_error_buffer); + gfc_clear_diagnostic_buffer (pp_error_buffer); } @@ -916,8 +852,8 @@ gfc_clear_error (void) bool gfc_error_flag_test (void) { - return error_buffer.flag - || !gfc_output_buffer_empty_p (pp_error_buffer); + return (error_buffer.flag + || !pp_error_buffer->empty_p ()); } @@ -928,18 +864,10 @@ bool gfc_error_check (void) { if (error_buffer.flag - || ! gfc_output_buffer_empty_p (pp_error_buffer)) + || ! pp_error_buffer->empty_p ()) { error_buffer.flag = false; - pretty_printer *pp = global_dc->m_printer; - output_buffer *tmp_buffer = pp_buffer (pp); - pp_buffer (pp) = pp_error_buffer; - pp_really_flush (pp); - ++errorcount; - gcc_assert (gfc_output_buffer_empty_p (pp_error_buffer)); - pp_buffer (pp) = tmp_buffer; - diagnostic_action_after_output (global_dc, DK_ERROR); - diagnostic_check_max_errors (global_dc, true); + global_dc->flush_diagnostic_buffer (*pp_error_buffer); return true; } @@ -954,21 +882,18 @@ static void gfc_move_error_buffer_from_to (gfc_error_buffer * buffer_from, gfc_error_buffer * buffer_to) { - output_buffer * from = &(buffer_from->buffer); - output_buffer * to = &(buffer_to->buffer); + diagnostic_buffer * from = &(buffer_from->buffer); + diagnostic_buffer * to = &(buffer_to->buffer); buffer_to->flag = buffer_from->flag; buffer_from->flag = false; - gfc_clear_pp_buffer (to); - /* We make sure this is always buffered. */ - to->m_flush_p = false; + gfc_clear_diagnostic_buffer (to); - if (! gfc_output_buffer_empty_p (from)) + if (! from->empty_p ()) { - const char *str = output_buffer_formatted_text (from); - output_buffer_append_r (to, str, strlen (str)); - gfc_clear_pp_buffer (from); + from->move_to (*to); + gfc_clear_diagnostic_buffer (from); } } @@ -995,7 +920,7 @@ gfc_pop_error (gfc_error_buffer *err) void gfc_free_error (gfc_error_buffer *err) { - gfc_clear_pp_buffer (&(err->buffer)); + gfc_clear_diagnostic_buffer (&(err->buffer)); } @@ -1028,12 +953,10 @@ gfc_diagnostics_init (void) diagnostic_format_decoder (global_dc) = gfc_format_decoder; global_dc->m_source_printing.caret_chars[0] = '1'; global_dc->m_source_printing.caret_chars[1] = '2'; - pp_warning_buffer = new (XNEW (output_buffer)) output_buffer (); - pp_warning_buffer->m_flush_p = false; + pp_warning_buffer = new diagnostic_buffer (*global_dc); /* pp_error_buffer is statically allocated. This simplifies memory management when using gfc_push/pop_error. */ pp_error_buffer = &(error_buffer.buffer); - pp_error_buffer->m_flush_p = false; } void diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index a55646d..dd599bc 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3490,12 +3490,13 @@ bool gfc_notify_std (int, const char *, ...) ATTRIBUTE_GCC_GFC(2,3); #define gfc_syntax_error(ST) \ gfc_error ("Syntax error in %s statement at %C", gfc_ascii_statement (ST)); -#include "pretty-print.h" /* For output_buffer. */ +#include "diagnostic-buffer.h" /* For diagnostic_buffer. */ struct gfc_error_buffer { bool flag; - output_buffer buffer; - gfc_error_buffer(void) : flag(false), buffer() {} + diagnostic_buffer buffer; + + gfc_error_buffer(); }; void gfc_push_error (gfc_error_buffer *); |