mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
fortran: dynamically allocate error_buffer [PR117442]
PR fortran/117442 reports a crash on exit of f951 when configured with --enable-gather-detailed-mem-stats. The crash happens if any diagnostics were ever buffered into error_buffer. The root cause is that error_buffer is statically allocated and thus has a non-trivial destructor called at exit. If error_buffer's diagnostic_buffer ever buffered anything, then a diagnostic_per_format_buffer will have been created for the buffer per-output-sink, and the destructors for these call into the mem-stats subsystem, which has already beeen cleaned up. The simplest fix is to allocate error_buffer on the heap, rather that statically, which fixes the crash. There's a comment about error_buffer: /* pp_error_buffer is statically allocated. This simplifies memory management when using gfc_push/pop_error. */ added by Manu in r6-1748-g5862c189c2c3c2 while fixing PR fortran/66528. The comment appears to be out of date. I've tested maxerrors.f90 under valgrind, and it's clean with the patch. gcc/fortran/ChangeLog: PR fortran/117442 * error.cc (error_buffer): Convert to a pointer so it can be heap-allocated. (gfc_error_now): Update for error_buffer being heap-allocated. (gfc_clear_error): Likewise. (gfc_error_flag_test): Likewise. (gfc_error_check): Likewise. (gfc_push_error): Likewise. (gfc_pop_error): Likewise. (gfc_diagnostics_init): Allocate error_buffer on the heap, rather than statically. (gfc_diagnostics_finish): Delete error_buffer. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
2e35fbd1fd
commit
8c4184682d
@ -43,7 +43,7 @@ static bool warnings_not_errors = false;
|
||||
/* True if the error/warnings should be buffered. */
|
||||
static bool buffered_p;
|
||||
|
||||
static gfc_error_buffer error_buffer;
|
||||
static gfc_error_buffer *error_buffer;
|
||||
static diagnostic_buffer *pp_error_buffer, *pp_warning_buffer;
|
||||
|
||||
gfc_error_buffer::gfc_error_buffer ()
|
||||
@ -707,7 +707,7 @@ gfc_error_now (const char *gmsgid, ...)
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
error_buffer.flag = true;
|
||||
error_buffer->flag = true;
|
||||
|
||||
va_start (argp, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR);
|
||||
@ -842,7 +842,7 @@ gfc_internal_error (const char *gmsgid, ...)
|
||||
void
|
||||
gfc_clear_error (void)
|
||||
{
|
||||
error_buffer.flag = false;
|
||||
error_buffer->flag = false;
|
||||
warnings_not_errors = false;
|
||||
gfc_clear_diagnostic_buffer (pp_error_buffer);
|
||||
}
|
||||
@ -853,7 +853,7 @@ gfc_clear_error (void)
|
||||
bool
|
||||
gfc_error_flag_test (void)
|
||||
{
|
||||
return (error_buffer.flag
|
||||
return (error_buffer->flag
|
||||
|| !pp_error_buffer->empty_p ());
|
||||
}
|
||||
|
||||
@ -864,10 +864,10 @@ gfc_error_flag_test (void)
|
||||
bool
|
||||
gfc_error_check (void)
|
||||
{
|
||||
if (error_buffer.flag
|
||||
if (error_buffer->flag
|
||||
|| ! pp_error_buffer->empty_p ())
|
||||
{
|
||||
error_buffer.flag = false;
|
||||
error_buffer->flag = false;
|
||||
global_dc->flush_diagnostic_buffer (*pp_error_buffer);
|
||||
return true;
|
||||
}
|
||||
@ -903,7 +903,7 @@ gfc_move_error_buffer_from_to (gfc_error_buffer * buffer_from,
|
||||
void
|
||||
gfc_push_error (gfc_error_buffer *err)
|
||||
{
|
||||
gfc_move_error_buffer_from_to (&error_buffer, err);
|
||||
gfc_move_error_buffer_from_to (error_buffer, err);
|
||||
}
|
||||
|
||||
|
||||
@ -912,7 +912,7 @@ gfc_push_error (gfc_error_buffer *err)
|
||||
void
|
||||
gfc_pop_error (gfc_error_buffer *err)
|
||||
{
|
||||
gfc_move_error_buffer_from_to (err, &error_buffer);
|
||||
gfc_move_error_buffer_from_to (err, error_buffer);
|
||||
}
|
||||
|
||||
|
||||
@ -955,9 +955,8 @@ gfc_diagnostics_init (void)
|
||||
global_dc->m_source_printing.caret_chars[0] = '1';
|
||||
global_dc->m_source_printing.caret_chars[1] = '2';
|
||||
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);
|
||||
error_buffer = new gfc_error_buffer ();
|
||||
pp_error_buffer = &(error_buffer->buffer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -970,4 +969,7 @@ gfc_diagnostics_finish (void)
|
||||
diagnostic_text_finalizer (global_dc) = gfc_diagnostic_text_finalizer;
|
||||
global_dc->m_source_printing.caret_chars[0] = '^';
|
||||
global_dc->m_source_printing.caret_chars[1] = '^';
|
||||
delete error_buffer;
|
||||
error_buffer = nullptr;
|
||||
pp_error_buffer = nullptr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user