aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-10-23 10:54:42 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-10-23 10:54:42 -0400
commitf565063a0602ad3b48ac687f575dea7a90cd4105 (patch)
tree3cd13dc9544d4111e590d5b29e4b60c3ea6436b6 /gcc/fortran
parentde2dc62379b7a2c93e11b03804380af072fd249b (diff)
downloadgcc-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.cc149
-rw-r--r--gcc/fortran/gfortran.h7
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 *);